5.1 MySql基础

5.1.1 MySql数据类型

数值类型

整数类型:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT。分别占用1、2、3、4、8个字节。并可以存储不同的储值范围。

例如TINYINT可以存在-127至128之间的整数;BIGINT可以存储范围在-9,223,372,036,854,775,808到9,223,372,036,854,775,807之间的整数

浮点类型:FLOAT,DOUBLE。用于存储单精度和双精度浮点数,分别占用4、8各个字节。FLOAT可以存储大约7位精度的浮点数,DOUBLE可以存储大约15位精度的浮点数

定点数类型:DECIMAL,NUMERIC。用于存储精确的值。

字符串类型

                     定长字符串类型:CHAR

                     变长字符串类型:VARCHAR

                     其他字符串类型:TEXT(大文本数据)、BLOB(二进制对象)等

日期时间类型

                     存储年月日:DATE

                     存储时间信息:TIME

                     存储年月日和时间信息:DATETIME

                     存储时间戳信息:TIMESTAMP

布尔类型:使用TINYINT(1)表示,可以存储true和false的值

5.1.2 锁机制

1.作用:解决资源共享造成的并发问题

2.锁分类

按照操作类型分:

  读锁(共享锁):对同一个数据,多个读操作,可以同时进行,互不干扰

  写锁(排他锁):当前写操作没有结束,无法进行其他的读、写操作          

 按照操作范围分:

    表锁: 一次性针对一张表整体进行加锁。如MyISAM存储引擎使用表锁,开销小,加锁快;无死锁;但是锁范围大,容易发生锁冲突、并发度低

    行锁:一次性针对一条数据加锁,如InnoDB存储引擎使用行锁,开销大,加锁慢;容易出现死锁,锁范围小,不易发生锁冲突,并发度高。

    页锁:开销和粒度介于表锁和页锁之间,会出现死锁,并发度一般 

3.表锁基本使用

加锁相关命令:

加读锁-命令:LOCK TABLES '表名' READ;

加写锁-命令:LOCK TABLES '表名' WRITE;

释放锁:unlock tables;

查看加锁的表:show open tables; 1表示被加了锁

分析表锁的严重程度:show status like 'table%';

Table_locks_immediate:即可能获取到的锁数

Table_locks_waited:需要等待的表锁数(如果该值越大,说明存在越大的锁竞争)。

一般建议:Table_locks_immediate/Table_locks_waited > 5000, 建议采用InnoDB引擎,否则MyISAM引擎

192.168.11.101(1)会话给表t_user加读锁(共享锁)

示例:lock tables 't_user ' read;

结论:某会话对A表增加读锁,则该会话可对此表进行查询操作,无法进行写操作。也不能对其他表进行读、写操作;如果某会话给A表增加读锁,其他会话可对A表进行读操作,但是写操作需要等待原会话释放锁;其他会话可以针对其他表进行读、写操作       

192.168.11.101(1)会话给表t_user加写锁(排他锁)

 示例:lock tables 't_user' write;

结论:某会话对A表增加写锁,则该会话对此表可以进行任何操作,但是不能操作其他表

如果某会话给A表增加写锁,其他会话可对此表进行操作,前提是原会话释放掉锁;其他会话可以针对其他表进行读、写操作

4.行锁基本使用

       前提:mysql默认自动commit;oracle默认不会自动commit;暂时将自动commit关闭命令:set autocommit = 0;start transaction;begin;

       相关说明:通过索引对记录进行加锁,包括共享锁和排他锁;共享锁(S Lock)可让事务读取记录,但不能修改记录;排他锁(X Lock)可让事务读取并修改记录

     在InnoDB引擎中,默认使用行锁,通过索引来锁定行的,如果SQL没有使用索引或者索引失效,那么InnoDB会使用表锁

       命令:select ... LOCK IN SHARE MODE; 通过select 给某行数据添加共享锁

                SELECT ... FOR UPDATE ; 通过select 给某行数据添加排他锁

                示例:

                 -- 使用SELECT ... LOCK IN SHARE MODE获取共享锁

                 SELECT * FROM table_name WHERE condition LIMIT 1 LOCK IN SHARE MODE;

                

                 -- 使用SELECT ... FOR UPDATE获取排他锁

                 SELECT * FROM table_name WHERE condition LIMIT 1 FOR UPDATE;

                

                行锁分析:show status like '%innodb_row_lock%';

                Innodb_row_lock_current_waits:当前正在等待锁的数量。

                Innodb_row_lock_time:等待总时长。从系统启动到现在一共等待的时间。

               

                Innodb_row_lock_time_avg:平均等待时长。从系统启动到现在平均等待的时间。

               

                Innodb_row_lock_time_max:最大等待时长。从系统启动到现在最大一次等待的时间。

               

                Innodb_row_lock_waits:等待次数。从系统启动到现在一共等待的次数。

       总结:在先关闭自动提交的前提下,某会话针对一条数据进行加锁,其他会话针对此数据操作必须先等原会话释放掉锁(commit或者rollback),但是可以针对其他数据进行操作。

       行锁的特殊情况:间隙锁(值在范围内,但却不存在)

              示例:t_role有id为1,2,3,4,6,7,8的数据,如果此时执行 update t_role set code = 'x' where id >1 and id <9;

                       即在此范围内没有id=5的数据,则id=5的数据成为间隙.

                       mysql会自动给间隙添加间隙锁。上述示例中会自动给id=5的数据添加间隙锁/行锁。

       缺点:比表锁性能损耗大

       优点:并发能力强,效率高。高并发使用InnoDB存储引擎,否则使用MyISAM

5.MySql死锁

       定义:两个或多个事务在同一资源上相互占有资源,而又在等待其他事务释放资源,从而导致无法向前推进的情况

       预防:确保事务有序访问资源,减少事务持有锁的时间,保证相同的锁顺序

       通常解决方法:回滚其中一个事务

       检验是否死锁:SHOW ENGINE INNODB STATUS;

                              或者通过innodb_print_all_deadlocks配置项记录死锁日志,前提是InnoDB监控开启此功能,开启此功能在配置文件中设置innodb_print_all_deadlocks=1,重启即可

                              频繁死锁可能导致日志迅速膨胀,生产环境谨慎使用

参考资料:https://blog.csdn.net/weixin_55076626/article/details/128532271   

                https://blog.csdn.net/jkzyx123/article/details/123716477

5.1.3 事务

定义:由单独单元的1个sql或多个sql组合而成,单元中每个sql相互依赖,单元是不可分隔的整体,里面的内容要么全部执行成功,要么全部失败。

与存储引擎的关系:InnoDB支持事务,MYISAM和MEMORY不支持事务。show engines;查看存储引擎。

特性:

    原子性(Atomicity):事务是不可分隔的最小执行单位,要么全部成功要么全部失败

    一致性(Consistency):事务必须使数据库从一个一致状态转换为另一个一致状态。例如张三给李四转账50.事务中会减少张三50,增加李四50.一致性是指其他事务要么看到张三还没给李四转账,要么已经看到张三少了50,李四多了50.

     隔离性(Isolation):一个事务内部的操作和使用的数据对其他事务是隔离的,并发执行的事务之间不可互相干扰

    持久性(Durability):一个事务一旦提交成功,对数据库中数据的改变是永久的,后续操作不应对其有影响

分类:

                     隐式事务:没有明显的开启和结束标记,具有自动提交事务的功能

                            DML语句(insert、update、delete)  

                     显示事务:有明显的开启和结束标记,使用显示事务前提是将自动提交事务功能给关闭,即将autocommit的变量值设置为0(1为开启,0为关闭)。set autocommit = 0;

                            查看是否自动提交事务:select @@autocommit;

开启事务步骤

                     start transaction;

                     编写事务执行sql;(insert、update、delete)

                     commit;或者rollback; (提交或者回滚事务)

事务并发可能出现的问题

                     脏读:两个事务S1,S2,S2读取了S1更新但还未提交的数据,若S1回滚,S2读取的数据是无效的

                     幻读:两个事务S1,S2,S2在表中读取了一个字段,然后S1在表中插入了一些新的数据,S2再读取此表时,会莫名多出现一些数据

                     不可重复读:两个事务S1,S2,S2读取了一个字段,S1将此字段更新后,S2再次读同一字段,值不相同了

事务的隔离级别

                     读未提交(read uncommitted):允许事务读取未被其他事务提交的变更。脏读、幻读、不可重复读都可能出现

                     读已提交(read committed):只允许事务读取已被其他事务提交的变更。幻读、不可重复读都可能出现

                     可重复读(repeatable read):确保事务可以多次从一个字段中读取相同的值,在此事务期间,禁止其他事务对此字段进行更新。幻读可能出现

                     串行化(serializable):确保事务可以从一张表中读取相同的行,在此事务期间,禁止其他事务对此表进行插入、更新、删除操作。所有并发问题都可避免,但性能很低。

                            oracle支持两种事务隔离级别:读已提交、串行化,默认事务隔离级别是读已提交

                            mysql事务默认隔离级别是可重复读

                            查看事务隔离级别:select @@tx_isolation; mysql8.0之后采用select @@transaction_isolation;

                           

                            #设置当前mysql连接的隔离级别:

                            set session transaction isolation level read uncommitted;

                            #设置数据库系统的全局的隔离级别:

                            set global transaction isolation level read uncommitted;

事务的保存点(回滚点)

                     回滚点表示的是事务回滚到指定回滚点。

                     使用语法:savepoint 节点名称;

                     注意事项:只能搭配rollback一起使用

参考资料:https://blog.csdn.net/qq_56880706/article/details/122653735

5.1.4 MVCC(多版本并发控制)

                     前提了解:

MVCC:

                            定义:全称Multi-Version Concurrency Control,即多版本并发控制。是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。

                            作用:MVCC在MySql InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式处理读写冲突,即便有读写冲突时,也能做到不加锁,非阻塞并发读。

MVCC本质

                            为了实现快照读-写冲突不加锁;当前读是一种加锁的操作,是悲观锁的实现

                            MVCC在mysql中的实现是由3个隐式字段,undo日志,Read View等去完成的  

MySQL InnoDB下的当前读和快照读

                            当前读:共享锁(select lock in share mode )、排他锁(select for update            ,update,insert,delete)等都是当前读,因为读取的是记录的最新版本,读取时还需保证其他事务不会影响当前记录,会对读取的记录进行加锁

                            快照读:不加锁的select就是快照读,即不加锁的非阻塞读;

                                          快照读的前提是隔离级别非串行级别,串行级别下的快照读会退化成当前读;

                                          快照读的出现是基于提高并发性能的考虑,快照读实现基于MVCC,MVCC是行锁的一个变种,但它在很多情况下,避免了加锁,降低了开销。

                                          快照读不一定读取的是最新的数据,可能是历史版本的数据

                     当前读、快照读和MVCC之间的关系

                            MVCC是 维持一个数据的多个版本,使读写操作没有冲突 的概念,并非实现

                            快照读是MySQL实现MVCC理想模型的其中一个非阻塞读功能;当前读就是悲观锁的具体功能实现。

 MVCC解决什么问题:

                            数据库并发场景有以下3种类,分别是

                                   读-读:不存在问题,无需并发控制

                                   读-写:有线程安全问题,可能遇到脏读、幻读、不可重复读

                                   写-写:有线程安全问题,可能存在更新丢失问题

MVCC好处

                            解决读-写冲突的无锁并发控制

                            并发读写数据库时,读操作和写操作不会相互阻塞,提高了数据库并发读写的性能

                            解决脏读、幻读、不可重复读等事务隔离问题,但不能解决更新丢失问题

                     MVCC是为了避免单一采用悲观锁解决读写冲突提出的解决方案,

                     在数据库中,MVCC可以分别和悲观锁、乐观锁进行阻塞

                            MVCC+悲观锁 MVCC解决读写冲突,悲观锁解决写写冲突

                            MVCC+乐观锁     MVCC解决读写冲突,乐观锁解决写写冲突

                            以上两种方式可最大程度提高数据库并发性能,并解决读写冲突、写写冲突导致的问题

MVCC实现原理:依赖记录中的3个隐式字段,undo日志,Read View来实现的

                     隐式字段:每行数据除了自定义字段外,还有数据库隐式定义的 DB_TRX_ID, DB_ROLL_PTR, DB_ROW_ID 等字段

                            DB_TRX_ID:6 byte,最近修改(修改/插入)事务 ID:记录创建这条记录/最后一次修改该记录的事务 ID

                            DB_ROLL_PTR:7 byte,回滚指针,指向这条记录的上一个版本(存储于 rollback segment 里)

                            DB_ROW_ID:6 byte,隐含的自增 ID(隐藏主键),如果数据表没有主键,InnoDB 会自动以DB_ROW_ID产生一个聚簇索引

                     undo日志:主要分两种

                            insert undo log:insert新纪录时产生的undo log,只在事务回滚时需要,事务一旦提交则立即丢弃

                            update undo log:update或delete时产生的undo log,事务回滚和快照读时都需要,所以不可随意丢弃,只有在快速读或事务回滚不涉及该日志时,对应日志才会被purge线程统一清除

                            purge:InnoDB的MVCC机制,更新或删除都是设置下deleted——bit,并非真将数据删除,purge是InnoDB中专门清理deleted-bit为true的记录的线程

Read View读视图

                            Read View就是事务进行快照读操作时产生的读视图,是数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(每个事务开启时,都会分配一个ID,这个ID是递增的,事务越新,ID越大)

参考资料:https://blog.csdn.net/SnailMann/article/details/94724197

                https://zhuanlan.zhihu.com/p/421769708   

5.1.5 存储引擎(Innodb,MyISAM)

              定义:存储引擎是数据库底层软件组织,数据库使用存储引擎进行创建、查询、更新、删除数据。

              mysql存储引擎查询命令:SHOW ENGINES;

              mysql常见存储引擎:

                     InnoDB:事务性数据库首选引擎,MySQL的默认存储引擎

                     MyISAM:基于ISAM存储引擎,并对齐进行扩展

                     MERGE:一组MyISAM表的组合

                     MEMORY:将表的数据存储到内存中

                     ARCHIVE:仅支持插入和查询两种功能

                     CSV:将CSV类型的文件当作表进行处理

                     BLACKHOLE:黑洞引擎,支持事务,支持mvcc的行级锁,写入此引擎的数据都会消失

                     PERFORMANCE_SCHEMA:用于收集服务器性能参数

                     Federated:将不同的mysql服务器联合起来,组成一个完整的数据库

              存储引擎如何选择:查看参考资料

              参考资料:https://blog.csdn.net/yjclsx/article/details/81911027

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值