MySQL锁
执行操作时施加的锁模式
读锁:共享锁
写锁:独占锁,排它锁
锁粒度:
表锁:table lock
锁定了整张表
行锁:row lock
锁定了需要的行
粒度越小,开销越大,但并发性越好;
粒度越大,开销越小,但并发性越差;
锁的实现位置:
MySQL锁:可以使用显式锁
存储引擎锁:自动进行的(隐式锁);
显式锁(表级锁):
LOCK TABLES
UNLOCK TABLES
LOCK TABLES
tbl_name lock_type
[, tbl_name lock_type] ...
锁类型:READ|WRITE
mysql>lock tables classes READ;
如果这个时候向classes插入数据的话 会停在那里不动,直到解锁
mysql>unlock tables;
mysql>lock tables classes write;
这个时候插入与查询都会等待,直到解锁;
mysql>unlock tables;
InnoDB存储引擎也支持另外一种显式锁(锁定挑选出的部分行,行级锁 ):
SELECT ... LOCK IN SHARE MODE;
SELECT ... FOR UPDATE;
mysql>select * from classes where ClassID <=3 lock in share mode;
mysql>show table status like 'classes'; --查看引擎是哪种
mysql>show tables status\G --
mysql>alter table classes engine 'InnoDB'; --测试下,生产不手动锁,用系统默认锁就可。
mysql>show table status like 'classes'\G
mysql>select * from classes where ClassID <=3 lock in share mode;
事务及隔离级别
事务:Transaction --innodb的表结构和NDB,BDB的表结构可以支持事务
事务就是一组原子性的查询语句,也即将多个查询当作一个独立的工作单元。
ACID测试:能满足ACID测试就表示其支持事务,或兼容事务。
A:Atomicity,原子性
C:Consistency, 一致性
I: Isolation, 隔离性, 一个事务的所有修改操作在提交之前对其它事务是不可见的
Tom: 7000-3000
Jerry: 5000+3000
D:Durability, 持久性, 一旦事务得到提交,其所做的修改会永久有效
隔离级别:
1>READ UNCOMMITTED (读未提交)--- 能够看到别人尚未提交的数据;数据安全性不好,用得很少;
脏读,不可重读,幻读 ---XX对表做了操作还未提交,YY就可以看到效果,如XX删除表CLASSES某一行,还未提交,YY查询就看不到那一行了,XX执行回滚后,YY又会看到回滚后的结果;
2>READ COMMITTED (读提交) --- 一般数据库是这个,不过mysql是第三种;对事务要求不严格的话建议用这个;
不可重读,幻读
---启动显示事务,XX对表进行修(未提交),YY查看这个表时显示XX未操作的内容,当XX操作提交后,YY查询的内容仍然是XX未提交前内容,只有当YY执行提交后才会看到XX修改提交后的内容。
3>REPEATABLE READ (可重读)
幻读 ---显示事务启动后,XX对表classes做相修改,YY查询表时,是原表,当XX提交后,YY在查询这个表时还是原表(可重读);只有当YY当前事务提交后,才会看到XX做的修改;
4>SERIALIZABLE (可串行化)
强制事务的串行执行避免了幻读; --显示事务启动后,XX事务对表CLASS做了修改未提交前,YY事务对表查询时会产生阻塞(等待),等XX,提交或回滚后才可执行;
跟事务相关的常用命令
mysql>help contents
mysql>help Transactions
mysql> START TRANSACTION
mysql> COMMIT --提交
mysql> ROLLBACK
mysql>help rollback --回滚
mysql> SAVEPOINT identifier --保存点
mysql>help savepoint
mysql> ROLLBACK [WORK] TO [SAVEPOINT] identifier
演示
mysql>start transaction
mysql>select database();
mysql>select * from classes;
mysql>delete from classes where ClassID=10;
mysql>select * from classes;
mysql>ROLLBACK
mysql>select * from classes; ---未提交前,所有操作都可回滚到未操作前
mysql>delete from classes where ClassID=10;
mysql>commit; --提交后,就不能回滚了
mysql>start transaction;
mysql>delete from classes where ClassID=4;
mysql>savepoint a;
mysql>delete from calsses where ClassID=9;
mysql>savepoint b;
mysql>select * from classes;
mysql>rollback to b;
mysql>select * from classes; --回滚b以后所有操作
如果没有显式启动事务,每个语句都会当作一个独立的事务,其执行完成后会被自动提交;
mysql>show global variables like '%commit%';
可以看到 autocommit on 即 每个语句都自动提交,每次都会产生一个IO
mysql> SELECT @@global.autocommit; 跟上面命令一样 查询autocommit 状态
mysql> SET GLOBAL autocommit = 0;
关闭自动提交,请记得手动启动事务,手动进行提交;
查看MySQL的事务隔离级别
mysql> SHOW GLOBAL VARIABLES LIKE 'tx_isolation';
mysql> SELECT @@global.tx_isolation;
修改:
mysql>set global tx_isolation='READ-UNCOMMITTED';
重新建立连接看一下效果
mysql>use hellodb;
mysql>start transaction;
mysql>select * from classes;
开连接 都开启各自事务 可以做一些操作查看一下各级别的效果;
mysql>start transaction; 两个会话都执行
建议:对事务要求不特别严格的场景下,可以使用读提交;性能比默认要好;
MVCC:多版本并发控制
每个事务启动时,InnoDB为会每个启动的事务提供一个当下时刻的快照;
为了实现此功能,InnoDB会为每个表提供两隐藏的字段,一个用于保存行的创建时间,一个用于保存行的失效时间;
里面存储的是系统版本号;(system version number)
只在两个隔离级别下有效:READ COMMITTED和REPEATABLE READ
MySQL存储引擎
存储引擎也通常称作“表类型”
mysql> SHOW ENGINES;
mysql>show variable like '%engine%';
mysql>select version(); --查看数据库版本
mysql>desc t1; --查看表结构
mysql>show create table t1; --查看创建表t1时的sql语句
mysql> SHOW TABLES STATUS [LIKE clause] [WHERE clause]
SHOW TABLE STATUS [{FROM | IN} db_name]
[LIKE 'pattern' | WHERE expr]
mysql>show table status;
mysql> SHOW TABLE STATUS IN hellodb WHERE Name='classes'\G
mysql> show table status in hellodb like 'classes';
mysql>show engine innodb status; ---查看innodb表的运行状态
*************************** 1. row ***************************
Name: classes
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 8
Avg_row_length: 2048
Data_length: 16384
Max_data_length: 0
Index_length: 0
Data_free: 9437184
Auto_increment: 9
Create_time: 2014-04-08 11:14:52
Update_time: NULL
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.01 sec)
Name: 表名
Engine: 存储引擎
Version: 版本
Row_format: 行格式
{DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}
Rows: 表中的行数
Avg_row_length: 平均每行所包含的字节数;
Data_length: 表中数据总体大小,单位是字节
Max_data_length: 表能够占用的最大空间,单位为字节
Index_length: 索引的大小,单位为字节
Data_free: 对于MyISAM表,表示已经分配但尚未使用的空间,其中包含此前删除行之后腾出来的空间
Auto_increment: 下一个AUTO_INCREMENT的值;
Create_time: 表的创建时间;
Update_time:表数据的最近一次的修改时间;
Check_time:使用CHECK TABLE或myisamchk最近一次检测表的时间;
Collation: 排序规则
Checksum: 如果启用,则为表的checksum;
Create_options: 创建表时指定使用的其它选项;
Comment: 表的注释信息
InnoDB:
两种格式
1、innodb_file_per_table=OFF,即使用共享表空间
每张表一个独有的格式定义文件: tb_name.frm
还一个默认位于数据目录下共享的表空间文件:ibdata#
2、innodb_file_per_table=ON,即使用独立表空间
每个表在数据库目录下存储两个文件:
tb_name.frm
tb_name.ibd
MyISAM:
每个表都在数据库目录下存储三个文件:
tb_name.frm
tb_name.MYD
tb_name.MYI
表空间:table space,由InnoDB管理的特有格式数据文件,内部可同时存储数据和索引
如何修改默认存储引擎:通过default_storage_engine服务变量实现
mysql>show engines;
mysql>show variable like '%engine%';
各存储引擎的特性:
InnoDB:
事务:事务日志-- #cd /data/mydata/ ib_logfile0/1
外键:
MVCC:
聚簇索引:
聚簇索引之外的其它索引,通常称为辅助索引
行级锁:间隙锁
支持辅助索引
支持自适应hash索引
支持热备份
MyISAM:
全文索引
压缩:用于实现数据仓库,能节约存储空间并提升性能
空间索引
表级锁
延迟更新索引
不支持事务、外键和行级锁
崩溃后无法安全恢复数据
适用场景:只读数据(读多写少;如果innodb设置为读提交的话也比myisam要好)、较小的表、能够容忍崩溃后的修改操作和数据丢失
mysql>show table status in mysql\G
ARCHIVE:
仅支持INSERT和SELECT,支持很好压缩功能;
适用于存储日志信息,或其它按时间序列实现的数据采集类的应用;
不支持事务,不能很好的支持索引;
CSV:
将数据存储为CSV格式;不支持索引;仅适用于数据交换场景;
BLACKHOLE:
没有存储机制,任何发往此引擎的数据都会丢弃;其会记录二进制日志,因此,常用于多级复制架构中作中转服务器;
MEMORY:
保存数据在内存中,内存表;常用于保存中间数据,如周期性的聚合数据等;也用于实现临时表
支持hash索引,使用表级锁,不支持BLOB和TEXT数据类型
MRG_MYISAM:是MYISAM的一个变种,能够将多个MyISAM表合并成一个虚表;
NDB:是MySQL CLUSTER中专用的存储引擎
第三方的存储引擎:
OLTP类:
XtraDB: 增强的InnoDB,由Percona提供;
编译安装时,下载XtraDB的源码替换MySQL存储引擎中的InnoDB的源码
PBXT: MariaDB自带此存储引擎
支持引擎级别的复制、外键约束,对SSD磁盘提供适当支持;
支持事务、MVCC
TokuDB: 使用Fractal Trees索引,适用存储大数据,拥有很压缩比;已经被引入MariaDB;
列式存储引擎:
Infobright: 目前较有名的列式引擎,适用于海量数据存储场景,如PB级别,专为数据分析和数据仓库设计;
InfiniDB
MonetDB
LucidDB
开源社区存储引擎:
Aria:前身为Maria,可理解为增强版的MyISAM(支持崩溃后安全恢复,支持数据缓存)
Groona:全文索引引擎,Mroonga是基于Groona的二次开发版
OQGraph: 由Open Query研发,支持图结构的存储引擎
SphinxSE: 为Sphinx全文搜索服务器提供了SQL接口
Spider: 能数据切分成不同分片,比较高效透明地实现了分片(shared),并支持在分片上支持并行查询;
索引类型:
聚簇索引
辅助索引
B树索引
R树索引
hash索引
全文索引
如何选择?
是否需要事务
备份的类型的支持
崩溃后的恢复
特有的特性