mysql DBA(五)innodb引擎

 其中innodb就是图中的存储引擎。

一、表空间、buffer pool、压缩表

1、页

 在磁盘的数据文件中称为数据页,在mysql内存中称为缓存页。不过大小一般都是16k。

页是IO交互的最小单位。(在磁盘文件和buffer pool交互的最小单位)

可以对页的大小进行压缩,KEY_BLOCK_SIZE=4就是压缩为4k,此时这张表就是压缩表。

但不是压缩的越低就越好,不同的场景压缩越低其指标不一样。

 

 row offset array:有序的存放指向各个row的指针,用来快速定位数据页中的各个记录。(相当于一个目录)

数据格式默认是compact,dynamic和compact基本一样,除了在存储大对象时dynamic会对其进行优化。

对于大对象,compact只存大对象的前768个字节超出部分则会存在溢出页中(期间也会触发超8k触发行溢出),而dynamic存满一个页后触发行溢出则存到其他溢出页中,依次存储(行溢出:再创建一个页,将溢出的部分存到其他页,然后进行指针指向记录)。(一般size>页大小的一半,则触发行溢出现象。超过8k则会将超出的部分存到其他页。)

数据存储格式?行溢出?为什么是8k???
——一行数据为多大时,会发生行溢出呢?我们知道InnoDB存储引擎表是索引组织的,即B+树结构,这样一个页中至少要保证有2条数据(所以超过页大小一半就触发行溢出,会将溢出的数据放到其他页中并指针指向。这个页剩下的一半存其他数据),否则就变成链表了(???目前看不懂),如果只能存放一条数据,那么InnoDB存储引擎会自动将它存放在溢出页中。如果可以在一个页中至少放入两行数据,那么就不会发生行溢出。

https://www.jb51.net/article/200618.htm

【MYSQL】InnoDB行溢出数据说明_ITPUB博客


索引中的页的每个row记录都会包含一个rowid(默认主键,没有mysql则会自动建立一个rowid)、txid(事务id)等等.


2、buffer pool(缓冲池)

用innodb_buffer_pool_size参数来控制大小。

之前的数据页就会被读到缓冲池中(内存)(在缓冲池中叫做缓存页)。

对于标记某个页用(space,page_no)其中space表示表空间id,page_no表示页号。所以要定位到磁盘的页需要知道其对应的表空间+页号。

可以查看每张表对应的表空间id:

 查看缓冲池里有哪些页:

 但是这个数据可能太大,线上不要轻易去查看。

buffer pool一般越大越好。

在缓冲池中存在一个hash表来存储已经在buffer pool中的缓冲页信息。

 mysql的锁是占内存空间的,5.5之后是直接调用操作系统的malloc()函数申请内存的,而不是向buffer pool申请内存。


压缩后的数据在页中怎么存储的?(即innodb压缩表)

旧的压缩方式:

因为页是被压缩了的,例如一个8k的页被读到bp中,然后这个压缩的页会被解压。这样就可以对这个页进行查询操作。

如果要对这个页进行更新操作:此时这个8k的压缩页被读到bp,然后将对这个页的重做日志redo log(也叫modification log 更新日志)写到这个页的空闲空间中,如果这个页被写满了则再重新进行压缩,如果压缩完还是不够就会重新申请一个同等大小的压缩页用来存储,最后将这些压缩页写回磁盘。这样这些更新时压缩页就不用做解压。

对于没压缩的16k就不做日志写入而是直接去做更新。

注意:16k没压缩的不会做日志记录操作,直接做更新操作。 

一般建议可以开启压缩。


新的压缩方式:

透明页压缩,5.7新增的压缩算法。

在linux中,如果有一个文件大小是16k,此时里面的数据占12k,那么此时在文件后面填0至16k满,此时调用linux的fwrite写入磁盘,此时这个文件在磁盘的占用空间就是12k。

而透明页就是利用这点,如果一个16k的页,此时里面的数据被压缩到8k,剩下8k空闲区域,此时我们往其中填0(注意这里的压缩后的数据空间只能是操作系统块大小的倍数,即4k的倍数,如果压缩后的数据大小是6k,哪进磁盘后还是按4*2=8k进行占用),然后写入磁盘,此时在磁盘中这个页只会占用8k。

这样读取/更新这些透明页压缩算法的压缩页时,会解压为16k的页进行读取。这种新的压缩算法比较简洁高效。(都是以默认页大小进行交互存储的,老压缩是以压缩后大小进行存储交互的)

这种透明页压缩是比老压缩算法高效一些的。

一般使用lz4压缩算法进行透明页压缩。

这里压缩还是不太明白????


buffer pool对其中的页进行管理时,都会对buffer pool加一个latch锁(轻量级锁)。

此时为了提高并发能力,可以设置一个innodb_buffer_pool_instances参数为cpu的核数:

 如果buffer pool size太小这个参数会被刷为1.

此时如果我们给 buffer pool总的内存是1G,如果我们不配这个参数,那么就是只给一个buffer pool配置1G内存。

如果设置为例如4,那么此时会有4个buffer pool,每个256G。

这样加的latch就会是不同的buffer pool的latch锁(锁粒度减少了)(latch锁的是bp的一些资源)

5.6、5.7版本默认值是8。5.5是1。如果是5.5版本记得要调整其参数。

二、LRU、Master_Thread

buffer pool中有free list、lru list、flush list。

其中lru list又分LRU、unzip_LRU。

 这些链表是基于页连接起来的。所以buffer pool基本等于free + LRU。(flush存在LRU中)

free list:管理bp中空闲的页。

lru list:管理已用的页(包含脏页和非脏页)

flush list:存放更新了的脏页。(该链存放的是指针)

链表都是在页中存储上下页节点形成的。所以这些链都是通过各个页的信息连接起来的。

1、LRU

如果一个页被使用了,此时需要将该页在free list上删除,并添加到lru list中,加入lru list是插入到一个midpoint位置上,该位置大概在链长3/8的位置。

最近最少使用算法:如果某个页被free list读到lru就会放到最前面链表头过去。

midpoint LRU:某个页从free list读到lru list,此时先放到midpoint的位置,如果后续有使用会被调到链表头的位置。(这样防止一些扫描进来却没用的页占用表头位置)(mysql默认)

其中midpoint 有参数停顿时间:innodb_old_black_time(待满停顿时间后才能移到链表头),控制midpoint位置参数:innodb_old_blocks_pct。

 MySQL是如何对LRU算法进行优化的?又该如何对MySQL进行调优?_天堂的博客-CSDN博客


预热

可以执行select+使用索引预热常用的表,但是这种方法是比较粗糙的。

5.6开始可以dump出buffer pool的数据,然后重启mysql后load这些数据进入buffer pool

 此时dump出来的不是所有数据,而是这些页的space+pageno(还会进行排序,这样读取页的时候可以尽可能的减少读消耗)。


innodb后台线程:

 从名字可以大概知道是一些日志线程、读写线程、刷新脏页线程(默认4个)、监控线程、dump线程等等。

可以调整这些线程的个数,例如调大写线程个数:

 1、脏页刷新线程:page_cleaner_thread

默认4个,可以通过innodb_io_capacity参数进行控制。

 一般每1秒最多刷新8000个脏页。

预读:关于MySQL buffer pool的预读机制 - GeaoZhang - 博客园


CheckPoint

 主要用来刷新脏页,将脏页刷新到磁盘。

每个页都有一个LSN,整个mysql实例也有一个LSN(这个LSN也是checkPoint)。当页进行更新时,其LSN页会进行更新。每个数据库宕机恢复时,会读取数据库实例的LSN然后去日志中恢复数据。而全局的LSN是刷到磁盘的页的LSN的最大值。

  恢复checkPoint(全局lsn)之后的所有数据(即从120开始恢复,checkpoint之前的已经写入磁盘了),这样就可以防止页2的最新数据丢失。(页2事务提交了就会记录到redo log中,但页此时还没刷到磁盘中)

 其中log sequence number表示内存中日志的lsn,

log flushed up to是磁盘中日志记录的最大lsn,

pages flushed up to是bp中页最大的lsn,

last chechpoint at 是全局lsn。

此时可以发现全局lsn是小于等于页最大lsn和日志lsn的?
这个时候我们假如现在有一个页的lsn是80,此时进行第一次更新为100,此时由于是第一次更新全局会进行刷新(全局记录的是第一次更新的lsn),然后全局刷新为100。此时又对该页进行更新,产生了20字节的日志,那么该页的lsn会变为120,而全局lsn因为是第二次更新则不会刷新该值,所以全局还是100,然后该页会被添加到flush list页中。

注意,flush list是按照第一次进来链表是的lsn进行排序位置的,所以当第二次更新这个页使得其lsn变为140,但是在flush list中,这个页的lsn还是120。(flush list只按第一次进来的lsn进行排序)

而我们刷新脏页是去flush list中刷新的,此时我们把这个120的页刷新到磁盘中

为什么全局在第二次更新不会记录最新的lsn值?

此时我们回来讲讲全局lsn是怎么改变的?

 在这里可以看到newset_modification和oldset_modification,分别代表页最新的lsn和页改第一次的lsn。

而我们全局lsn用的就是oldset_modification,即记录的都是页的改的第一次lsn,而pages flushed up to的lsn是记录的newset_modification。(上面有个例子说页1和页2的情况是页改第一次的情况,才会使得全局lsn刷新)

此时只要保证每个页只更新一次,那么全局和page的lsn就会相等。

全局lsn、日志lsn都被存放到重做日志redo log中。

哪为什么要记录第一次更新的lsn??
——为了恢复的时候,日志的恢复是对的。现在假如flush list有140、120的页,此时120的页如果再次更新使得lsn变为160,此时如果全局lsn记录的是最新的lsn,那么恢复数据的时候会从160开始恢复,这样就导致140这个可能存在丢失的情况。

这里我有一个疑问?如果全局记录的是140,但是我120还没进行刷磁盘的时候就宕机了,此时恢复是从140开始恢复???如果是那不是丢失了120的页???为什么checkpoint前的数据是都被刷进磁盘的???

——checkpoint即全局lsn被记录的时机是页刷到磁盘了。(checkpoint是被记录到redo log文件的。)

MySQL InnoDB Checkpoint技术_weixin_35833012的博客-CSDN博客

这里的check point技术是fuzzy checkpoint。


 刷新脏页不一定是都在flush list中进行刷新。

也有一些情况会取lru list中刷新脏页:

当free list没有空闲的页,此时又要申请一个空页就会把LRU最后一个页进行淘汰,如果该页是脏页则进行刷盘操作。

可以用一个参数配置每次淘汰时扫描多个页进行刷盘操作:

即每次没空页时,会找lru尾端1024个页对其中的脏页进行刷盘操作。


 double write(双写)

InnoDB关键特性之double write - GeaoZhang - 博客园

redo log恢复的页需要这个页是完整的,如果某个页假如是16k,在写入磁盘写到一半(例如写了4k进磁盘)就发生宕机,此时这个页就是损坏的,此时是不能通过redo log进行恢复的。

即一个页写了两次。此时磁盘的doublewrite可以防止损坏页不能恢复。(默认打开的功能)


 

 提升二级索引增删改的性能。(先存放在内存中(insert buffer会进行持久化),后面辅助索引读进bp在进行合并)


 自适应hash索引

建议关闭。页数据改变导致维护代价太大。

 自适应hash索引的对象是热点页里面的数据,b+树索引的对象是页。


 对于ssd硬盘建议把这个功能关闭。

事务、undo log、redo log

事务原子性:redo保证,持久性:redo+undo,一致性:undo,唯一性:锁机制

事务可以自己手动开启提交(显示事务),如果没有显示提交mysql会隐式的为我们提交事务。(所以隐式提交每次执行sql可以当成一个事务)

事务隔离级别:

 事务需要解决三个问题:脏读、不可重复读、幻读。

1、redo log

 redo log buffer刷盘时机:

 每次刷一个事务日志可能性能比较低,此时mysql有个优化组提交(多个事务日志一起提交)

 有两个参数可以控制提交触发的时间或者达到多少个事务就提交:(一般不要调)

 mysql的组提交一般不用去调整,mysql已经帮我们优化了可以了。自己去修改可能会导致性能下降。 

5.6优化的组提交比5.5提升性能8-10倍。

 mysql默认可以有两个redo log日志文件。可以通过innodb_log_file_size指定文件大小;用innodb_log_files_in_group来指定文件个数。


binlog:

其中T1、T2等是事务提交顺序。

binlog日志记录的是sql语句的操作,而redo log日志记录的是对页(space,page_no)的修改。(其记录的对象不同)

而redo log对在一个事务中是可以多次修改页的,所以会出现多个T1。

redo 日志是在事务执行过程就开始写了,而二进制日志binlog是在事务提交最后的时间才开始写。

重做日志一般用于复制等场景,建议开启:

 


怎么保证redo 和binlog写入的原子性?(redo和binlog写完才进行事务提交)

当redo和binlog都刷盘完之后,此时就要将本次更新的binlog文件名+这次更新在文件中的位置   记录到redo文件中,并在写完后加入commit标志。

那么这个commit标记有什么用,要记住只有图中的5、6、7步都执行完才叫真正的事务完成,如果第5步完成后宕机或第6步完成后宕机,此时redo没有commit标记,那么这个事务也算是没提交成功的,只有redo中有commit标记才表示事务的提交成功。

        如果redo、binlog都写完最后没commit就宕机了,恢复时去扫描binlog拿到事务id去创建一个hash表,然后在去redo log扫描checkpoint位置然后也会生成一个事务列表,此时如果事务列表的某个事务存在hash表中(则表示redo和binlog写完成了),则会进行恢复操作。

写某个事务日志是不能跨日志文件写的。


undo :记录逻辑(redo记录物理),用于事务回滚。

 可以看我之前的undo文章

mysql除了支持本地事务外,还主从分布式事务XA。

 回滚:

mysql中 XA分布式事务MySQL 中基于 XA 实现的分布式事务 - 简书

mysql 事务中如果有sql语句出错,会导致自动回滚吗? - 怀素真 - 博客园

锁的概念:

 latch锁:(轻量级锁)(用来控制内存中数据结构、临界资源的并发访问,即类似我们java中的锁,锁住的对象是临界区)(latch锁的加锁释放锁过程是很快的,毫秒级别的)

例如现在执行count++操作,此时对于count这个对象可能有并发安全问题,此时就要加上latch锁进行控制(互斥锁)。

 lock锁:(锁的是数据库层面的锁,innodb的锁住的对象是行,保护的是数据库中的内容)

 lock锁的持续时间是整个事务,如果事务没被提交,会一直持有。

其实两种锁的应用层面是不同的,latch我们可以理解为java中我们对某个对象的并发安全控制,而lock是对于行数据的保护。



lock:

 1、排他锁(X)

对某行进行增删改时需要对该行记录加排他锁。

select要加上排他锁可以在语句最后加上for update,不过此时如果其他会话也是可以通过mvcc机制读这条记录的。

2、共享锁(S)

给一条记录加上共享锁:追加lock in share mode

 锁等待时间默认是50秒(会话级别的)

 可以通过show engine innodb status可以查看mysql中的锁情况:

 例如持有3把锁:

 想要详细查看各个锁的信息,此时可打开打印详细信息锁的参数:

此时再看:可以看到有个IX表意向锁。还有记录锁(行锁X)且打印相应的行记录(其中trd和d是隐藏列,分别对应事务id和指针)。

这里可以看到各个记录存在heap no 2、3之类的。head no表示数据插入的顺序。而插入的顺序不代表数据大小的顺序。

在一个页中,存在mysql自己生成的heap no 0和1,这是用来存放虚拟的最小记录和最大记录的。如果此时插入heap  no 2。则里面heap no的指向是0-2-1。再插入3则变为0-2-3-1。

一般对某行数据进行加锁,是根据page no+heap no来定位的。

此时加锁:

(lock bitmap这个位图是整个页的所有heap no)而heap no是在这个位图中表示的第几位,例如2表示第二位,此时如果位图中的第二位为1则表示为加锁了。

 mysql是一个页对应一个锁对象,以页为单位进行锁对象管理的。

不过其占用内存比较小,每个页的锁对象大概几十个字节。

mysql——innodb(学习笔记)_忘记过去的人,必将重蹈覆辙-CSDN博客


 意向锁:

 意向锁都是表级别的。

意向锁之间都是不互斥的。innodb不仅仅有行锁,还有意向锁等表锁。

如果我们要像表a的第n行加一个x锁,此时第一步就是要对表a加一个IX锁,然后在对行n加X锁。S和IS类似。为什么之前说意向锁是不互斥的,就是因为意向锁顾名思义就是我之后有要加某个锁的意向,即先预先说明下我下面可能要加X锁或者S锁。

意向锁和行锁中:只要意向共享锁+共享锁、意向独占锁+独占锁(互斥锁)是不互斥的。

行锁中:只要共享锁+共享锁不互斥。

而且共享锁和互斥锁是存在行级和表级的。

所以如果此时又有一个线程要进来给a表加一个S锁,此时表a就同时存在IX和S,此时互斥所以加锁不成功,就会进行等待。

加锁是需要进行层级加锁的,先对表加锁、然后是行数据。


查看mysql中锁等待的情况:
去sys.innodb_lock_waits表中查看各个锁等待的情况:


自增锁:对于自增列的并发处理的。

 在5.7中自增列有数据回溯问题(5.7在每次启动是去执行MAX(auto_inc_col)函数获取最大值,全表扫描)。8.0对自增的最大值做持久化解决了这个问题。

如果我们以自增列做索引时,需要将自增列作为最左的索引字段,否则会报错:

如下面a为自增列,以a和b建组合索引,此时a不是在最左列则会报错。

 自增锁其实实际上就是latch锁,执行完语句就释放,不会因为事务是否提交才释放锁。

 innodb_autoinc_lock_mode参数的设置对应意义:默认是1(这里被我设置为2了)MySQL自增锁模式innodb_autoinc_lock_mode参数理解调优 - WidgetBox - 博客园


 

 

 innodb的RR事务级别是可以解决幻读的问题的。

可以想想是怎么解决幻读的?

锁的算法

 锁算法主要分为:记录锁、范围锁、范围+记录锁。

1、记录锁

对于行数据进行加锁,实际上是对其索引进行加锁。记录锁就是加了X锁。

2、范围锁

例如现在主键索引有记录2、4、6、8四行记录。

此时加上范围锁可以是(2,100)2到100范围内的记录加X锁。

注意记录锁和范围锁是兼容的。即线程a对行2-100持范围锁,那么此时线程b同样可以对行2持记录锁但是不能进行数据的修改(只能进行加锁不能进行数据修改)。但是如果线程a已经对2-100持范围锁,此时线程b要去修改这个范围的行例如行2就需要等待访问锁的释放。

3、范围+记录锁。(也是innodb在RR级别解决幻读的关键)

例如对2-100加范围锁,且对2这条记录加记录锁。

该锁和前面的两种锁算法不兼容。

RR事务隔离级别用的锁算法大部分使用next-key锁算法(范围+记录),这个算法有一个问题就是插入的性能优点慢。有小部分情况下会进行优化使用record锁(语句使用的索引是唯一索引,且只返回一条记录的情况下)。

RC事务级别的锁大部分是记录锁。

在RC事务级别中可以看到查看mysql中锁的情况时,这里写着rec but not gap,则表示是record锁算法。


 RR级别下怎么解决幻读的:(RR级别,所以一般都是用next-key算法)

 mysql加锁是一条记录一条记录进行加锁的,所以这里不是直接4-8,然后再对6进行加锁。

那么为什么要去锁住(6,8)的区间?不是锁主6就行了吗??(为了解决幻读情况)

此时如果在这个事务执行过程中,其他事务新插入一条6的记录,此时会放到原本6的后面,即放到了(6,8)的区间了。

 那么这个时候就会产生幻读的情况(幻读:第二次读取读到原先不存在的数据),此时innodb的RR级别是可以防止幻读的,所以此时会对(6,8)进行加gap锁(新插入的6是存在这个区间的),防止其他事务插入同样的6。这样就不会产生幻读的情况了。(解决幻读就是对返回的记录的后面一个区间加上gap锁防止插入相同的数据)(这里也有一个情况就是4-6、6-8这个区间被加gap锁,那么此时插入4、5、7之类的记录也是不行的需要等待)

(主键索引也是类似的推导过程,锁算法其实锁的是索引 。又因为二级索引的叶子索引是key+主键,二级索引会对二级索引+主键索引都进行加锁(这里主键锁的只是4这个值,记录锁))

如果是RC时只会对6的记录使用记录锁,只锁住这一行。


 延续前面的例子,我们知道被主键索引被锁住是4,二级索引被锁住的是(4,6】、

(6、8)。

那么此时我们插入(主键、二级索引列)的值为(3,4)此时不能插入,因为二级索引列中有4这个记录,此时插入会放在相同的4之后,所以就会在4-6的范围内。

那么此时再插入(1,4)发现可以插入。这个时候就有疑问了,4不是在4-6区间吗,怎么可以插入成功????

其实在二级索引中,所谓的(4,6】、(6、8)。真实的情况下是

((4,2),(6,4)】、((6,4),(8,6))。即二级索引因为叶子节点且包含主键值,所以此时如果(4,1)插入不属于((4,2),(6,4)】区间,可以插入成功。

但是(4,2)这种里面已经有的值还是属于((4,2),(6,4)】区间不能插入。

(所以前面说的二级索引中4插入位置是不一定在原有4之后的,要搭配主键一起看。)


假如现在现在二级索引列b有值4、6、8、10。

让后我们执行b=12 for update;这时12这条记录是没有的,此时查看mysql中锁的情况:

 可以发现此时锁的是heap no 1,即我们之前说的mysql自己生成的虚拟列最大记录。

如果加上虚拟列,b的真实数据是{min、4、6、8、10、max}。

而此时12不存在这些数据中,此时会在max记录进行加锁,此时则会锁住(10,max】、(max,正无穷)区间。所以此时插入大于10的都不行。(等于10的要搭配主键一起看是否能插入)。

同理,此时如果b=7 for update,

 此时则会在8上加gap锁(gap before rec即锁住前面区间),即锁住了(6,8)区间。

如果lock_mode后面没有提示使用什么锁,则默认是net-key锁。


在RC级别中,如果对不存在的记录加锁,此时不会加任何锁,因为RC不需要解决幻读问题。


如果我们现在查询时没用索引??
例如我们现在往表再假如一个列c,然后执行c=100 for update;(100的记录存在,且其对应的主键列值为4)。

1、RC情况下:

此时我查看加锁情况:

 这里可以知道此时如果sql没用到索引,此时会对对应的主键进行加锁。

2、RR情况下:

查看锁情况:

 此时会发现锁住的范围:

 即相当于锁住了所有记录。此时锁的代价就会很大。

那为什么要锁全表???
这也是为了防止幻读。我们都知道,c不是索引,非唯一的二级索引列会锁主键和二级索引,所以重复的值也不用锁全表就可以保证幻读问题,而非索引字段此时的范围太大需要锁全部。


在RC级别下:

 此时会话1先删除小于等于7,此时对这四个值加记录锁。所以会话2是可以插入的。

此时我们再看看这个过程binlog日志是怎么记录的:(记录先提交的)

 此时因为会话2先提交,此时先记录insert 2,然后再记录del 。

那么此时如果mysql中存在主从结构,需要用binlog日志做同步。此时就会出现:

  此时先insert 2,所以slave的数据是1、2、3、5、7。然后再执行del操作,此时所有记录都会被删掉。那么此时就存在主从数据不一致的问题了。

那么此时怎么解决??

此时就要设置一个参数为row。

 此时binlog记录时,就不是直接记录del 小于等于7,而是记录del 1、del 3、del 5、del 7。

 这样就不会存在数据不一致的情况了。

(RC级别下的binlog_format一定要设置为row,防止主从数据不一致的情况)

此时要是del操作比较久,那会不会存在删到一半,insert 2插入了,然后把2也删了??
——不管是RC或者RR,del的过程是不会看到2的插入的。(readview或者锁机制决定了看不到),所以不存在因为del太久把2也给删了的情况。


readview:用来判断某条记录的可见性。

RR级别的MVVC机制+readview可以解决幻读???

  1. RR隔离级别,如果事务中都是快照读,或者全都是当前读,都不会产生幻读。只有当前读和快照读混用,才会产生幻读。
  2. MVCC保证快照读不会幻读
  3. next-key lock(间隙锁)保证当前读不会产生幻读

插入意向锁算法:

在RC中:

 在事务中插入一条数据:

然后查看mysql中锁情况,发现没有加锁的信息。

此时再开一个事务去select 刚才插入的 那条记录,此时却需要进行等待。再次去查看锁情况发现之前的那个insert语句的锁信息又出现了。

那么为什么之前insert的时候查看锁信息是没有的???

——innodb对其做了优化,insert的锁是隐式锁,就是不创建锁对象(减少内存消耗),当其他会话用到该记录了需要等待,此时才创建锁对象转换为显式锁。(类似于懒加载)


插入意向锁提升插入性能:


 死锁:

 等待图:自动进行死锁检测

 会根据锁的信息链+事务等待链推断出是不是存在死锁回路。

如果存在则回滚某个事务(通过undo的量来判断回滚的事务,回滚量比较少的)。

 show engine innodb status只会显示最后一次死锁的信息。

如果要记录所有死锁信息:开启参数innodb_print_all_deadlocks 

可以在配置文件中配置:

 这样死锁的信息都会记录到错误日志里面。

其中innodb_deadlock_detect参数可以关闭自动死锁检测。


mysql8.0新语法:
如果某行数据被锁了,此时使用下面进行加锁:

notwait就是不进行阻塞等待直接返回错误信息。

 skip locked:对被加锁的行数据直接跳过。


a

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
mysql 总结........................................................................................................................................6 1.1 数据库的种类...........................................................................................................6 1.1.1 关系型数据库介绍.................................................................................................6 1.1.2 非关系型数据库介绍.............................................................................................7 1.1.3 非关系型数据库种类.............................................................................................7 1.1.4 关系型数据库产品介绍.........................................................................................8 1.1.5 常用非关系型数据库产品介绍.............................................................................8 1.2 mysql 多实例安装实战......................................................................................................9 1.2.1 什么是 mysql 多实例? .........................................................................................9 1.2.2 mysql 的多实例结构图.........................................................................................10 1.2.3 实战安装 mysql 多实例需要的依赖包...............................................................10 1.2.4 安装编译 mysql 需要的软件...............................................................................10 1.2.5 安装 mysql 软件...................................................................................................11 1.2.6 创建存放两个 mysql 实例的数据目录...............................................................11 1.2.7 创建两个 mysql 多实例的配置文件...................................................................12 1.2.7.1 3306 的实例................................................................................................12 1.2.7.2 3307 的实例................................................................................................16 1.2.7.3 多实例本地登录 mysql .............................................................................20 1.2.7.4 远程连接登录 mysql 多实例....................................................................20 1.3 mysql 基础安全................................................................................................................21 1.3.1 启动程序设置 700,属主和用户组为 mysql .....................................................21 1.3.2 为 mysq 超级用户 root 设置密码........................................................................21 1.3.3 登录时尽量不要在命令行暴漏密码,备份脚本中如果有密码,给设置 700, 属主和用户组为 mysql 或 root......................................................................................21 1.3.4 删除默认存在的 test 库 .......................................................................................21 1.3.5 初始删除无用的用户,只保留 root 127.0.0.1 和 root localhost........................21 1.3.6 授权用户对应的主机不要用%,权限不要给 all,最小化授权,从库只给 select 权限.................................................................................................................................21 1.3.7 不要给一个用户管所有的库,尽量专库专用户...............................................21 1.3.8 清理 mysql 操作日志文件~/mysql_history.........................................................21 1.3.9 禁止开发获取到 web 连接的密码,禁止开发连接操作生产对外的库...........21 1.4.0 服务器禁止设置外网 IP ......................................................................................21 1.4.1 防 SQL 注入(WEB), php.ini 配置文件里面设置 ..........................................21 1.4.2 mysql 的备份的脚本给 700 的权限,并且属主和属组为 root..........................21 1.4 关于 mysql 的启动与关闭..............................................................................................21 1.4.1 单实例 MySQL 启动与关闭方法........................................................................21 1.4.2 多实例 MySQL 启动与关闭方法示例................................................................21 1.5 生产环境关闭 mysql 的命令..........................................................................................22 1.5.1 生产环境不能用强制命令关闭 mysql 服务 .......................................................22 1.5.2 下面来介绍优雅关闭数据库方法: ...................................................................22 1.6 登录 mysql 方法..............................................................................................................22 1.6.1 单实例 MySQL 登录的方法................................................................................22 1.6.2 多实例 MySQL 的登录方法................................................................................22 1.7 关于 mysql 管理员设置..................................................................................................22资源由 www.eimhe.com 美河学习在线收集分享 1.7.1 为管理员 root 用户设置密码并修改方法之一...................................................22 1.7.2 修改管理员 root 密码法二(sql 语句修改) .....................................................22 1.7.3 找回丢失的 mysql root 用户密码(单实例和多实例) ....................................23 1.8 SQL 结构化查询语言......................................................................................................23 1.8.1 什么是 SQL? ......................................................................................................23 1.8.2 SQL 语句最常见的分类一般就是 3 类 ...............................................................24 1.9 数据库的管理应用..........................................................................................................24 1.9.1 创建数据库...........................................................................................................24 1.9.2 查看库的字符集及校队规则...............................................................................24 1.9.3 企业场景创建什么字符集的数据库呢? ...........................................................26 1.9.4 显示数据库...........................................................................................................26 1.9.5 删除数据库...........................................................................................................26 1.9.6 进入数据库中指定的库.......................................................................................27 1.9.7 查看进入当前数据库的用户...............................................................................27 1.9.8 删除数据库多余的账号.......................................................................................27 1.9.9 查看数据库的用户...............................................................................................27 2.0.0 创建 MySQL 用户及赋予用户权限............................................................................27 2.0.1 使用语法:..............................................................................................................27 2.0.2 第一种创建用户及授权方法: ...........................................................................28 2.0.3 第二种创建用户及授权方法: ...........................................................................28 2.0.4 创建用户及授权哪个网段的主机可以连接 oldboy_gbk 库..............................29 2.0.4.1 第一种方法: .............................................................................................29 2.0.4.2 第二种方法: ............................................................................................29 2.0.5 关于 mysql 回收某个用户权限...........................................................................29 2.0.6 企业生产环境如何授权用户权限(mysql 主库) ............................................30 2.1 数据库表操作..................................................................................................................31 2.1.1 以默认字符集 latin1 建库....................................................................................31 2.1.2 建立表并查看表的结构.......................................................................................31 2.1.3 mysql 表的字符类型.............................................................................................32 2.1.3.1 数字类型.....................................................................................................32 2.1.3.2 日期和时间类型.........................................................................................32 2.1.3.3 字符串类型................................................................................................33 2.1.3.4 关于字符类型小结....................................................................................33 2.1.4 为表的字段创建索引...........................................................................................33 2.1.4.1 为表创建主键索引的方法........................................................................33 2.1.4.2 查看 student 表的结构 ..............................................................................34 2.1.4.3 怎么删除一个表的主键............................................................................34 2.1.4.4 利用 alter 命令修改 id 列为自增主键列..................................................34 2.1.4.5 建表后利用 alter 增加普通索引...............................................................34 2.1.4.6 对表字段的前 n 个字符创建普通索引....................................................36 2.1.4.7 为表的多个字段创建联合索引................................................................38 2.1.4.8 为表的多个字段的前 n 个字符创建联合索引........................................38 2.1.4.9 主键也可以联合多列做索引....................................................................39 2.1.5.0 统计一个字段列的唯一值个数................................................................40资源由 www.eimhe.com 美河学习在线收集分享 2.1.5.1 创建唯一索引(非主键) ........................................................................41 2.1.5.2 索引列的创建及生效条件........................................................................42 2.1.5 往表中插入数据...................................................................................................42 2.1.6 往表中删除一条数据...........................................................................................44 2.1.7 查询数据................................................................................................................44 2.1.7.1 查询表的所有数据行................................................................................44 2.1.7.2 查看 mysql 库的用户................................................................................45 2.1.7.3 根据指定条件查询表的部分数据............................................................45 2.1.7.4 根据固定条件查数据................................................................................46 2.1.7.5 指定固定条件范围查数据........................................................................46 2.1.7.6 根据顺序查看列数据................................................................................46 2.1.6.7 在表中根据条件导出数据至文件中........................................................47 2.1.8 多表查询...............................................................................................................47 2.1.8.1 创建学生表................................................................................................47 2.1.8.2 在学生表里插入数据.................................................................................47 2.1.8.3 创建课程表................................................................................................47 2.1.8.4 在课程表里插入数据................................................................................48 2.1.8.5 创建选课表................................................................................................48 2.1.8.6 联表查询命令............................................................................................49 2.1.9 使用 explain 查看 select 语句的执行计划..........................................................49 2.1.9.1 用查询语句查看是否使用索引情况........................................................49 2.1.9.2 为该列创建索引,再用查询语句查看是否走了索引............................50 2.2.0 使用 explain 优化 SQL 语句(select 语句)的基本流程..................................50 2.2.1 用命令抓取慢 SQL 语句,然后用 explain 命令查看查询语句是否走的索 引查询.....................................................................................................................50 2.2.2 设置配置参数记录慢查询语句...................................................................51 2.2.3 对抓取到的慢查询语句用 explain 命令检查索引执行情况 .....................51 2.2.4 对需要建索引的条件列建立索引...............................................................51 2.2.5 切割慢查询日志,去重分析后发给大家...................................................51 2.2.1 修改表中数据.......................................................................................................51 2.2.1.1 修改表中指定条件固定列的数据............................................................51 2.2.2 删除表中的数据...................................................................................................52 2.2.2.1 实践删除表中的数据................................................................................52 2.2.2.2 通过 update 伪删除数据...........................................................................53 2.2.3 增删改表的字段...................................................................................................53 2.2.3.1 命令语法及默认添加演示........................................................................53 2.2.4 更改表名...............................................................................................................55 2.2.5 删除表名...............................................................................................................56 2.2.6 mysql 数据库的备份与恢复.................................................................................56 2.2.6.1 备份单个数据库练习多种参数使用........................................................56 2.2.6.2 查看数据库 oldboy 的内容.......................................................................56 2.2.6.3 执行备份的命令........................................................................................57 2.2.6.4 查看备份的结果........................................................................................57 2.2.6.5 mysqldump 备份时加上-B 参数时的备份,然后比较不加-B 备份的不同资源由 www.eimhe.com 美河学习在线收集分享 .................................................................................................................................57 2.2.6.6 删除数据库中备份过的库 oldboy,然后将备份的数据重新导入数据库 .................................................................................................................................58 2.2.6.7 利用 mysqldump 命令对指定的库进行压缩备份...................................59 2.2.6.8 利用 mysqldump 命令备份多个库(-B 参数后可以指定多个库) ......59 2.2.6.9 分库备份(对 mysql、 oldboy、 oldboy_gbk、 wordpress 库进行备份) .................................................................................................................................60 2.2.7.0 对一个库的多个表备份............................................................................60 2.2.7.1 备份多个表................................................................................................61 2.2.7.2 备份单个表................................................................................................61 2.2.7.3 关于 mysqldump 的参数说明...................................................................61 2.2.7.4 刷新 binglog 的参数..................................................................................62 2.2.7.5 生产场景不同引擎 mysqldump 备份命令...............................................62 2.2.8 恢复数据库实践...................................................................................................63 2.2.8.1 数据库恢复事项........................................................................................63 2.2.8.2 利用 source 命令恢复数据库 ...................................................................63 2.2.8.3 利用 mysql 命令恢复(标准) ................................................................64 2.2.8.4 针对压缩的备份数据恢复........................................................................66 2.2.9 实现和 mysql 非交互式对话...............................................................................66 2.2.9.1 利用 mysql –e 参数查看 mysql 数据库的库名........................................66 2.2.9.2 利用 mysql –e 参数查看 mysql 数据库的线程状态................................66 2.2.9.3 mysql sleep 线程过多的问题案例............................................................66 2.2.9.4 查看 mysql 配置文件有没有在数据库中生效 ........................................67 2.2.9.5 不重启数据库修改数据库参数................................................................68 2.2.9.6 不重启数据库更改数据库参数小结........................................................69 2.3.0 查看 mysql 状态的信息(利用 zabbix 可以监控其状态信息) .......................69 2.3.1 mysqladmin 的命令...............................................................................................75 2.3.2 mysql 工具 mysqlbinlog........................................................................................76 2.3.2.1 mysql 的 binlog 日志是什么? ..................................................................76 2.3.2.2 mysql 的 binlog 日志作用是什么? ..........................................................76 2.3.2.3 mysqlbinlog 工具解析 binlog 日志实践....................................................76 2.3.2.4 解析指定库的 binlog 日志........................................................................76 2.3.3 mysql 数据库的服务日志.....................................................................................77 2.3.3.1 错误日志(error log)介绍与调整..........................................................77 2.3.3.2 普通查询日志(general query log)介绍与调整(生产环境中不用) 77 2.3.3.3 慢查询日志介绍与调整............................................................................78 2.3.3.4 二进制日志介绍与调整............................................................................78 2.3.4 mysql 的 binlog 有三种模式.................................................................................78 2.3.4.1 row level......................................................................................................78 2.3.4.2 statement level(默认) ..................................................................................79 2.3.4.3 Mixed ..........................................................................................................79 2.3.5 企业场景如何选择 binlog 的模式.......................................................................79 2.3.6 设置 mysql binlog 的格式....................................................................................79 2.3.7 mysql 生产备份实战应用指南.............................................................................80资源由 www.eimhe.com 美河学习在线收集分享 2.3.7.1 全量备份....................................................................................................80 2.3.7.2 增量备份....................................................................................................80 2.3.7.3 企业场景和增量的频率是怎么做的? ....................................................81 2.3.7.4 mysql 增量恢复必备条件..........................................................................81 2.3.7.5 实战模拟凌晨 00 点对 oldboy库做个全备,早上 10 点左右删除了 oldboy 库,下面是其恢复过程.........................................................................................81 2.3.7.6 实战模拟凌晨 00 点对 oldboy库做个全备,早上 10 点左右更新了 oldboy 库的 test 表中所有字段数据,下面是其恢复过程(update 表中的数据的时候, 把表中的字段换成了一个相同的内容,这时候要停库) .................................83 2.3.8 mysql 的主从复制的结构图.................................................................................85 2.3.8.1 单向的主从复制图,此架构只能在 master 端进行数据写入(生产环境 可以使用) .............................................................................................................85 2.3.8.2 双向的主主同步逻辑图,此架构可以在 master1 端或 master2 端进行数 据写入(生产环境不建议使用) .........................................................................85 2.3.8.3 线性级联单向双主同步逻辑图,此架构只能在 master1 端进行数据写入 (生产环境可以使用) .........................................................................................86 2.3.8.4 环状级联单向多主同步逻辑图,任意一个都可以写入数据(生产环境 不建议使用) .........................................................................................................86 2.3.8.5 环状级联单向多主多从同步逻辑图,此架构只能在任意一个 master 端 进行数据写入(生产环境不建议使用) .............................................................86 2.3.9 mysql 主从复制的原理.........................................................................................86 2.4.0 mysql 主从复制的原理图.....................................................................................87 2.4.1 mysql 主从复制的实践.........................................................................................87 2.4.1.1 环境准备....................................................................................................87 2.4.1.2 分别查看 3306 和 3307 不同数据库有哪些库........................................87 2.4.1.3 全量备份 3306 数据库的库,然后到 3307 数据库中............................88 2.4.1.4 在 3306 数据库上授权用户可以到 3306 数据库上复制 binlog.............89 2.4.1.5 在 3307 数据库上开启复制 3306 的 binlog 开关,并查看是否处于同步 状态.........................................................................................................................89 2.4.1.6 在 3306 上创建数据库 zhangxuan,看 3307 上是否同步过来..............91 2.4.2 关于主从复制出现故障怎么解决.......................................................................92 2.4.3 主从复制延迟问题原因及解决方案...................................................................92 2.4.3.1 一个主库的从库太多,导致复制延迟....................................................92 2.4.3.2 从库硬件比主库差,导致复制延迟........................................................92 2.4.3.3 慢 SQL 语句过多 ......................................................................................92 2.4.3.4 主从复制的设计问题................................................................................93 2.4.3.5 主从库之间的网络延迟............................................................................93 2.4.3.6 主库读写压力大,导致复制延迟............................................................93 2.4.4 通过 read-only 参数让从库只读访问..................................................................93 2.4.5 web 用户专业设置方案: mysql 主从复制读写分离集群..................................93 2.4.6 让 mysql 从库记录 binlog 日志方法...................................................................94 2.4.7 mysql 主从复制集群架构的数据备份策略.........................................................94 2.4.8 mysql 一主多从,主库宕机,从库怎么接管.....................................................95 2.4.8.1 半同步从库(谷歌半同步插件 5.5 版本自带) .....................................95资源由 www.eimhe.com 美河学习在线收集分享 2.4.8.2 S1,啥也不干只做同步的从库, 500 台服务器,百度..........................95 2.4.8.3 皇帝驾崩现选(耽误事,容易被篡位) ................................................95 2.4.9 事务介绍...............................................................................................................97 2.4.9.1 事务的四大特性(ACID) ......................................................................97 2.4.9.2 事务的开启................................................................................................97 2.4.9.3 事物的实现................................................................................................98 2.5.0 mysql 引擎概述.....................................................................................................98 2.5.0.1 什么是存储引擎? ....................................................................................98 2.5.0.2 mysql 存储引擎的架构..............................................................................99 2.5.0.3 myisaw 引擎介绍 .......................................................................................99 2.5.0.4 myisaw 引擎特点 .......................................................................................99 2.5.1 myisaw 引擎调忧精要 ........................................................................................100 2.5.2 innodb 引擎..........................................................................................................100 2.5.2.1 什么是 innodb 引擎? .............................................................................100 2.5.2.2 innodb 引擎特点.......................................................................................101 2.5.2.3 innodb 引擎适应的生产业务场景...........................................................102 2.5.2.4 关于 innodb 引擎的一些参数设置.........................................................102 2.5.2.5 innodb 引擎调忧精要...............................................................................102 2.5.3 有关 mysql 引擎特别说明.................................................................................103 2.5.4 关于 mysql 的字符集.........................................................................................103 2.5.4.1 mysql 常见的字符集? ............................................................................103 2.5.4.2 mysql 如何选择合适的字符集? ............................................................103 2.5.4.3 如何查看字符集......................................................................................103 2.5.4.4 不同字符集参数的含义如下(要想数据库字符不乱码,下面几个字符 集要相同) ...........................................................................................................104 2.5.4.5 set names 字符集名,此命令有什么作用 .............................................105 2.5.4.6 根据配置文件更改客户端字符集..........................................................105 2.5.4.7 更改 mysql 服务端的字符集..................................................................106 2.5.4.8 怎么解决乱码问题..................................................................................106 2.5.4.9 插入数据不乱码的方法..........................................................................106 2.5.5.0 更改数据库的字符集..............................................................................106 2.5.5.1 更改表的字符集......................................................................................106 2.5.6 模拟将 latin1 字符集的数据库修改成 UTF8 字符集的实际过程 ..................107
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值