锁和分区
锁
根据范围的不同:表级锁、行级锁、页级锁;
不同的存储引擎支持不同的锁;
Mysiam:表级锁
共享读锁:
读取表的一些内容时,mysql会给这张表加一个读锁,其他的会话可以给这张表加读锁,但是不能给这张表加写锁。
(可以读,不能写入数据,直到当前会话解锁为止)
加锁语法:lock table 表名 read;
解锁语法:unlock tables;
如果有多张表的话,如果给一张表加了锁,其他表没有加锁,那么在当前会话不能操作其他表,但是其他会话可以正常操作其他表。
如果其他表与当前表有关联,会出现数据不一致的情况,所以应该全部加锁。
(在其他会话中其他表可以写,加一个选项local:lock table 表名 read local;
前提是:这张表不能有黑洞,只能在最后一行插入
原因:mysql有一个变量:concurrent_insert,有三个值:
0:完全不允许插入;
1:默认值,没有黑洞的情况下可以插入;
2:无论有没有黑洞都,允许插入)
共享写锁: 我们对一张表的数据进行update、insert等操作时,mysql会自动给这张表加一个写锁,其他会话不能在加读锁或者写锁,直到解锁为止;
加锁语法:lock table 表名 write;
Innodb:行级锁(medefault)
前提是必须开启事务
行级锁,粒度更精细,适合大并发量插入,基于索引的锁,如果没有索引的话会使用表级锁。
缺点:
1.脏读:2.幻读:3.不可重复读
4.死锁:多个会话同时对同一个资源添加排它锁时,会出现死锁。
共享锁:
读取数据时,会给这行数据加一个共享锁,加了共享锁以后,其他会话可以加共享锁但是不能修改数据(不能加排它锁);
SELECT id,NAME FROM aa WHERE id=1 LOCK IN SHARE MODE;
排它锁: 所谓的排它锁就是写锁,对一行数据来写的时候,会给这一行内容加一个排它锁,其他会话不能加共享锁和排它锁。
SELECT id,NAME FROM aa WHERE id=1 FOR UPDATE;
查看加锁状况:show engine innodb status;
表分区(Mysiam)
(innodb默认使用共享表空间,可以先配置独立表空间,然后在分区)
可以使数据存放更加合理,方便查找,一个分区出现问题不会影响其他区分区。
分区的依据是根据表的某一列
使用之前,首先要确定是否支持和开起了分区
(show plugins;show variables ‘%partition%’;)
分区类型:
RANGE:
如果某一列是连续的(如id)
例子:CREATE TABLE aa( id INT )ENGINE=MYISAM PARTITION BY RANGE ( id(用来分区的列名))( PARTITION 分区名1 VALUES LESS THAN(10),#小于10放到分区1 PARTITION 分区名2 VALUES LESS THAN(20)#小于20放到分区2 );
此时大于20的数据无法插入;
解决增加一个分区:
ALTER TABLE aa ADD PARTITION ( PARTITION p4 VALUES LESS THAN(maxvalue) );大于等于20会放在分区4
删除分区:alter table 表名 drop partition 分区名;
查看数据在哪个分区:例:EXPLAIN PARTITIONS SELECT * FROM aa WHERE id=30;
查看表分区:SELECT * FROM information_schema.partitions WHERE table_name='表名';
LIST:
如果以某列作为分区列,指定具体的值放在某个分区里
例子:CREATE TABLE bb( id INT )ENGINE=MYISAM PARTITION BY LIST(id)( PARTITION p1 VALUES IN(1,3,5,7,9), PARTITION p2 VALUES IN(2,4,6,8,10) );
HASH:
不指定那些数据放在那个分区里,而是mysql会平均的把数据分配到这几个分区里
例子:CREATE TABLE cc( id INT )ENGINE=MYISAM PARTITION BY HASH(id) PARTITIONS 4;
以id为依据创建4个分区
KEY
按照key进行分区非常类似于按照hash进行分区,只不过hash分区允许使用用户自定义的表达式
与hash分区不用的是,key分区不允许使用用.于自定义的表达式,需要使用mysql服务器提供的hash函数,不需要hash分区那样对字段整型进行转换,
同时hash分区只支持整数分区,而key分区支,持使用出blob or text类型外的其他类型的列作为分区键。
和hash功能-样,不同的是分区的字段可以是非int类型,如字符串、日期等类型。
创建分区时,如果有唯一性索引或者主键索引,所选择的分区列必须是唯一性索引或者主键索引的一部分。