Things do not always work out. I'm working for a way out.
Published Jul 13, 2023
数据定义语言 Data Definition Language
show databases;
select database0;
create database [if not exists] base_name [default charset] [collate];
drop database [if exists] base_name;
use base_name;
#************************#
show tables;
desc table_name;
show create table;
create table table_name(
field_1 field_type [comment cmt],
...
)[comment cmt];
#************************#
alter table table_name modify target_field new_type(len);
alter table table_name change old_field new_field new_type(len) [comment cmt] [restrain];
alter table table_name drop field;
alter table table_name rename to new_table_name;
drop table [if exists] table_name;#删目录
truncate table table_name;#删内容
数据操作语言 Data Manipulation Language
insert into table_name(field1,...) values(val1,...);
insert into table_name values(val...);
insert into table_name(field1,...) values(val1,...),...;
insert into table_name values(val...),...;
#************************#
update table_name set field1=val1,... [where condition];
#************************#
delete from table_name [where condition];
数据查询语言 Data Query Language
select field1,... from table_name;
select * from table_name;
select field [[as] niknme],... from table_name;
select distinct field from table_name;
#************************#
select ... from table_name where condition;
select ... from table_name in (val1,...);
select ... from table_name between ... and ...;#[]
select ... from table_name like '_?' or '%?';
#************************#
select ... from ... [where con] group by evidence_field [hanving con];
select ... from ... order by field1 asc_desc,...;
#************************#
select ... from ... limit start_index, following_amount;
数据控制语言 Data Control Language
use mysql;
select * from user;
create user 'username'@'host' identified by 'pwd';
alter user 'username'@'host' identified with old_pwd by 'new_one';
drop user 'username'@'host';
#************************#
show grants for 'username'@'host';
grant grant_list on base.table to 'username'@'host';
revoke grant_list on base.table from 'username'@'host';
字符串函数
Concat(s1,…)
数值函数
日期函数
流程函数
关系
查询
内连接
外连接
自连接
Select … from A a1,A a2 where …
子查询
标量子查询、列子查询、行子查询、表子查询
@@autocommit=0 手动提交事务
commit 提交事务
rollback 回滚
事务的四大特性
事务并发存在的问题
隔离级别
Select @@transaction_isolation
set [session | global] transaction isolation level {level1234} |
加锁后,整个数据库实例就处于只读状态,典型场景:全库逻辑备份
flush tables with read lock;
mysqldump -uroot -p密码 basename > base.sql
终端执行
unlock tables
在InnoDB引擎中,可以在备份时加上参数–single-transaction来完成不加锁的一致性数据备份
lock tables name read/write
unlock tables
读锁阻塞写,写锁阻塞所有操作。
由系统自动控制,无需显式使用
事务A,B开启,操作对象表t
select ... lock in share mode
添加 与表锁共享锁兼容(read),与表锁排他锁(write)互斥
insert、update、delete、select ... for update
添加 与所有表锁互斥,意向锁之间不排斥
当表已经存在意向锁时试图加互斥表锁,会导致加表锁的事务线程阻塞,直到意向锁解除
锁定单行的纪录,防止其他事务update和delete
共享锁 S 排他锁 X 与之前类似
InnoDB使用next-key锁进行搜索和索引扫描,以防止幻读
锁定索引记录的间隙,不包含行记录,确保间隙不变,防止其他事务insert,不同事务的间隙锁可以兼容
InnoDB使用next-key锁扫描,
id | name | age |
---|---|---|
3 | PHP | 3 |
8 | Java | 4 |
A:update table set age = 10 where id = 5;
B:insert into table values(7,Python,7);
(blocked)
行锁和间隙锁的结合,同时锁住数据和间隙
锁的范围表示,间隙锁范围左开右闭。
一个mysql实例可以对应多个表空间,用于存储记录、索引等数据
InnoDB是索引组织表,数据段就是B+树的叶子结点,索引段为非叶子结点。段用来管理多个Extent
表空间的单元结构,每个区大小为1M。默认下InnoDB存储引擎页大小为16K,即一个区中一共有64个连续的页
InnoDB存储引擎管理磁盘的最小单元,每页大小默认16KB。为保证页的连续性,InnoDB每次从磁盘申请4-5个区
InnoDB数据是按行存放的
Master Thread
核心后台线程,负责调度其他线程,还负责将缓冲池的数据异步刷新到磁盘中,保持数据一致性,包括脏页刷新、合并插入缓存、undo页的回收
IO Thread
在InnoDB中大量使用了AIO来处理IO请求,这样可以极大地提高数据库性能,而IO Thread主要负责这些IO请求的回调
Purge Thread
主要用于回收事务已经提交了的undo log
Page Cleaner Thread
协助Master Thread刷新脏页到磁盘的线程,可以减轻Master Thread的工作压力,减少阻塞
特性的实现
redo log和undo log
锁和MVCC
重做日志,记录事务提交时数据页的物理修改,用于实现事务的持久性。
文件由两部分组成,重做日志缓冲和重做日志文件。当事务提交后,会把所有修改信息都存到该日志文件中,用于在刷新脏页到磁盘发生错误时进行数据恢复
回滚日志,记录数据被修改前的信息,作用包括提供回滚和MVCC
undo log不同于redo log,属于逻辑日志,其中记录的是实际操作的反向操作,如delete操作会使文件中增加insert记录。
Multi-Version Concurrency Control
当前读
读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对当前读取的记录进行加锁。select…lock in share mode, selcet… for update, update, insert, delete都是当前读
快照读
简单的select(不加锁)就是快照读,读到的是数据的历史版本,有可能是历史数据,不加锁是非阻塞读
MVCC——多版本并发控制,指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC具体实现依赖数据库记录中的三个隐式字段、undo log、realView
DB_TRX_ID
最近修改事务ID,记录插入这条记录或最后一次修改改记录的事务ID
DB_ROLL_PTR
回滚指针,指向这条记录的上一个版本,用于配合undo log指向上一版本
DB_ROW_ID
隐式主键,表结构本身没有主键会生成
回滚日志,当insert的时候,产生的undo log只在回滚时需要,事务提交后可被立即删除;而update、delete时,产生的undo log不仅在回滚时需要,在快照读时也需要,不会被立即删除。
undo log版本链
readview(读视图)是快照读执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交)的id
readview包含四个核心字段:
版本链数据访问规则:trx_id代表当前版本事务ID
不同的隔离级别,生成readview的时机不同:
结合undo log例子和readview规则理解