MySQL 扩展知识点
Grant和权限
Grant 语句会同时修改数据表和内存,判断权限的时候使用的内存数据,因此,规范的使用grant和revoke 语句,是不需要随后加上flush privileges。
flush privileges语句本身会用数据库的数据重建一份内存权限,所以在权限数据可能存在不一致的情况下再使用。而这种不一致往往是由于直接用DML语句操作系统权限导致的
My SQL系统自增id
表定义自增值id
表定义的自增值达到上限后的逻辑是:再申请下一个id时,得到的值不变。
InnoDB 系统自增 row_id
写入表row_id时从0开始到2^48-1。达到上限后,下一个值就是 0,然后继续循环。
Xid
MySQL内部维护了一个全局变量global_query_id,每次执行语句的时候将它赋值给Query_id,然后给这个变量加1。如果当前语句时这个事务执行的第一条语句,那么MySQL还会同时把Query_id赋值给这个事务的Xid。
MySQL重启后会生成新的binlog文件,这就保证了,同一个binlog文件,Xid一定时唯一的。达到上限后,就继续从0开始计数。
global_query_id定义的长度是8个字节,这个自增值的上限是2^64-1。
Innodb trx_id
Xid是由server层维护,InnoDB内部使用Xid,就是为了能够再InnoDB事务和server之间做关联。InnoDB 自己的 trx_id,是另外维护的。
InnoDB 内部维护了一个 max_trx_id 全局变量,每次需要申请一个新的 trx_id 时,就获得 max_trx_id 的当前值,然后并将 max_trx_id 加 1。
InnoDB 数据可见性的核心思想是:每一行数据都记录了更新它的 trx_id,当一个事务读到一行数据的时候,判断这个数据是否可见的方法,就是通过事务的一致性视图与这行数据的 trx_id 做对比。
thread_id
系统保存了一个全局变量thread_id_counter,每新建一个连接,就将thread_id_counter赋值给这个新连接的线程变量。thread_id_counter 定义的大小是 4 个字节,因此达到 232-1 后,它就会重置为 0,然后继续增加。
分区表的使用
MyISAM分区表使用的策略,称为通用策略,每次访问分区都由server层控制。通用分区策略,是MySQL一开始支持分区表就存在的,在文件管理、表管理的实现上很粗糙,因此有比较严重的性能问题。
MySQL5.7.9 ,InnoDB引擎引入了本地分区策略.InnoDB内部管理分区的行为。
1.MySQL在第一次打开分区表的时候,需要访问所有的分区;
2.在server层,认为这是同一张表,因此所有分区公用同一个MDL锁。
3.在引擎层,认为这是不同的表,因此MDL锁之后的执行过程,会根据分区表规则,只访问必要的分区。
Insert语句为什么加那么多锁
Insert….select 是很常见的在两个表之间拷贝数据的方法。在可重复读隔离级别下,这个语句会给select的表扫描到的记录和间隙加读锁。
如果insert和select的对象是同一个表,则有可能会造成循环写入,需要引入用户临时表来优化。
insert语句出现唯一键冲突,会在冲突的唯一值上加共享的next-key lock(S锁)。因此,要尽快提交或者回滚事务,避免枷锁时间过长。