mysq进化
学习来源:黑马程序员
存储引擎
存储引擎简介
存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎是基于表的,而不是基于库的,所以存储引擎也可被称为表类型
默认引擎——InnoDB
`
存储引擎特点
InnoDb
文件存储格式:xxx.ibd
xxx表示的是表名,innoDB引擎的每张表都会对应这样一个表空间,存储该表(frm、sdi)的表结构、数据和索引。
show variables like`innodb_file_per_table`;
#可以在对应的目录下找到对应的idb文件——对应的是二级制文件
逻辑存储结构:
MyISAM
不支持事务,不支持外键
支持表锁,不支持行锁
访问速度快
设计文件有:xxx.MYD\xxx.MYI\xxx.sdi(里面有json格式的字符串)
Menmory
存储在内存中,只能存放临时表
访问速度快,hash索引
文件:xxx.sdi
InnoDB 与MyISAM 的区别
InnoDB支持事务、使用行锁、并且支持外键,而MyISAM不支持事务且只有表锁,不支持外键
索引
是帮助Mysql高效获取数据的数据结构(有效)。载数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以载有些数据结构上实现高级查找算法,这种数据结构就是索引。
无索引——全表扫描
有索引的结构类似生成一颗平衡二叉树从而达到快速扫描的效果,这里只是说明一下
优点:提高查询效率、排序效率
缺点:使用存储空间换取时间快速,降低更新表的速度
数据结构
在存储引擎层实现——不同存储引擎使用不同索引
B+Tree树索引:常见的索引——中间节点向上分裂(B树),所有节点都存储在叶子结点——单向链表
Hash索引:底层数据结构是使用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范围查询——内存支持—,通过KEY-Value去解决该问题。
R-tree(空间索引):空间索引是MYIASM引擎的一个特殊搜索引擎类型,主要用于地理空间数据类型
Full-text(全文索引):是一种通过建立倒排索引,快速匹配文档的方式
所以在InnoDB存储引擎选择B+tree索引结构?
对于二叉树,层级更少,搜索效率高。
对于B-tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针跟着减少,要同样保存大量数据,值能增加树的高度,导致性能降低。
相对于Hash索引,B+tree支持范围匹配以及排序操作。
分类
主键索引、唯一索引、常规索引、全文索引
聚集索引:将数据存储与索引放到一块,索引结构的叶子节点保存了行数据,必须有且只有一个——主键、唯一索引、都没有会自动生成一个
二级索引:将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键,可以存在多个
所以可以通过二级索引找到主键值,再通过主键返回聚集索引中找到对应的
语法
创建CREATE [UNIQUE|FULLTEXT] INDEX index_name ON table_name (index_col_name,...);
查看SHOW INDEX FROM table_name;
删除DROP INDEX index_name ON table_name;
CREATE INDEX id_name_user on user (usr_name)
CREATE UNIQUE INDEX phone ON usr(phone_number)
CREATE INDEX profession_age_status ON user(profession,age,status)
DROP INDEX profession_age_status ON usr; //删除索引
SQL优化
慢查询日志记录了所有执行时间超过制定参数的所有SQL语句的日志。
MYSQL的慢查询日志默认没有开启,需要在MYSQL配置文件中(/etc/my.cnf)配置如下信息
slow_query_log=1 #开启
log_query_time=2 #设置慢日志的时间为2秒,如果超过2秒就会视为慢查询,记录慢查询日志
explain/desc select xxx
查看这个执行的步骤
其中这个执行的顺序会按照id的顺序执行,如果id值相同从上到下,不同则i越大越先执行
explain select s. *, c.* from students s,course c,student_course g where s.id = g.studentid && c.ud = g.courseid
select * from student s where no in(select studentid from student_course where courseid = (select id from course where name = 'Mysql') )
通过子查询就能得到id不同的越内部的id越大
索引使用
最左前缀法则:即使用联合索引的时候要注意先从定义联合所以的地方开始,否则索引会失效,如果跳过中间的索引就可能会导致缺失就会使后面的索引失效,如果最左的没有引用就会走全表扫描。
最左前缀法则和所放的位置没有关系
使用范围查询的时候右侧的列索引失效>符号失效要写>=才有用
show index from tb_user
查看当前表中的索引
在索引列上进行运算操作,索引将失效。
字符串索引不加’'`会失效变成全表查询
模糊查询中头部模糊匹配会失效——全表扫描
一列可能存在多个索引,就会导致需要选择特定的索引,此时就需要对索引进行筛选。
select * from tb_user use index(idx_user_pro) where profession= '软件工程' ;
use index(指定的索引名称)/ignore index(指定索引名称) /fotce index(指定索引名称) 建议使用那个索引/忽略那个索引/强制使用那个索引
覆盖索引:一条查询语句中,查询使用的列在改返回的列,在该索引中已经全部找到,减少select
通过 explian 查询后在extra里出现 using index condition表示的是查找使用索引,但是需要返回表查询数据——回表
using where;using index :查找使用了索引,但需要的数据都在索引列中能找到,所以不需要返回表查询
前缀索引:当字段类型(varchar 、text)为字符串时,有时候需要索引很长的字符串,这会让索引变得很大,查询时,浪费大量的磁盘IO,影响查询效率。此时可以直讲字符串的一部分前缀,建立索引,这样可以大大节约索引空间,从而提高索引效率
create index xxx on table_name(column(n))
表示我要按照全局第n个,建立索引。是一种B+树+链表的形式
选择性是指,不重复的/总数 越大越好
SQL优化
插入的SQL优化
insert 优化
手动提交事务+批量插入:
insert into tb_test values('1','Tom'),('2','Cat');
start transaction ;
insert into tb_test values('3','zom'),('4','Mat');
commit;
大批量插入数据:如果一次性需要插入大批量数据,使用insert语句插入性能较低,此时可以使用MysQL数据库提供的Load指令进行插入。本地文件符合要特定的要求
#客户端连接服务器时候,加上--local-infile 表示加赞本地的文件
mysql --local-infile -u root -p ;
#设置全局参数local_infile为1,开启从本地家在文件导入数据的开关
set global local_infile = 1 ;
#执行load指令将准备好的数据,加载到表结构中,其中.表示每个填表的格式 换行健表示一条数据
load data loca infile '/root/sql1.log' into table 'tb_usr' fields terminated by '.' lines terminated by '\n' ;
主键优化
在InnoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(IOT)
页分裂:表示的是主键插入的时候进行了乱序,类似B+树添加一个新的数字但这个数字是处于中间的。
页合并:删除一行的数据实际上并没有被物理删除,只是被标记了为删除的数据允许被其他记录使用,当页中删除的数据达到MERGE_THRESHOLD(默认为50%),InnoDB会开始寻找最靠近的页(前/后)就可以将两个页合并以达到两个页面优化
所以主键设计的时候:
1.满足业务前提的需求情况,尽量降低主键的长度
2.插入数据时,经历选择顺序插入,选择使用AUTO_INCREMENT自增主键
3.尽量不要使用UUID做主键或者其他自然主键,如身份证
4.业务操作时,避免对主键的修改
order by 优化
数据库排序操作:
Using filesor:通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sort buffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫FileSort排序
Using index:通过索引顺序 扫描直接返回有序数据,这种情况就是using index,不需要额外排序,操作效率高-创造索引的时候默认使用升序排列。
尽量使用覆盖索引
create index idx_usr_age on tb_user(age asc , phone desc);
limit 优化
在大数据的时候越往后耗时越大,所以消耗的时间越大,所以通过子查询的方式进行优化就可以实现。
count 优化
MyISAM 引擎吧一个表的总行数存在磁盘上,所以执行效率很高。
InnoDB 引擎就麻烦了,它执行count(*)的时候,需要把数据一行一行地从引擎里面读取出来,然后累计技术
count()是一个聚合函数,对于返回的结果集,一行行地判断,如果count函数的参数不是null,累计值就加1,否则不加,最后返回累计值
用法:count()=count(1)>count(主键)>count(字段)——每条返回的数字是1不是null就会加1
count(1):InnDB 遍厉整张表,但不取之。服务层对于返回的每一行,放一个数字“1”进去,直接按行进行累加。
count():服务器直接按行累加,不取值
update 优化
因为InnoDB 是行锁,所以事务开始的时候对改行进行操作,那么B就不能再对改行进行操作了。但是对其他行可以进行操作。
其中需要关心的是如果update 进行更新的时候没有添加索引那么就会是表锁,而不仅仅是行锁。——即需要全文扫描一次,如果一旦添加索引之后就可以变成行锁了。
视图/存储过程/触发器
视图
视图:是一种虚拟存在的表。视图中的数据并不在数据库汇中实际存在,行和列数据来自定义视图的查询中使用的表,并且在使用视图时动态生成的
通俗来说:视图只保存了查询SQL的逻辑,不保存查询的结果。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询上了
CREATE [OR REPLACE] VIEW 视图名称[列表名称] AS SELECT语句 [WITH[CASCADED|LOCAL|CHECH OPTION]]
其中OR REPLACE 表示的是替换某个视图,AS后面表示的就是要执行查询生成的数据封装
SHOW CREATE VIEW STU_V_1
表示查询视图的创建语句
SELECT * FROM STU_V_1
查询视图
修改视图需要添加OR REPLACE
CREATE OR REPLACE VIEW 视图名称[列表名称] AS SELECT语句 [WITH[CASCADED|LOCAL|CHECH OPTION]]
修改视图
ALTER VIEW 视图名称[列名列表] AS SELECT语句 [WITH[CASEDED|LOCAL] CHECK OPTION]
删除
DROP VIEW [IF EXISTS] 视图名称[,视图名称]...
执行增加的操作时:
insert into stu_v_1 values(6,'TOM');
其实不是对于该视图进行操作,而是在这个视图的基表上进行了操作,就是对原本的表进行了修改,所以是动态的。
其中使用CREATE [OR REPLACE] VIEW 视图名称[列表名称] AS SELECT语句 [WITH[CASCADED|LOCAL|CHECH OPTION]] WITH CASCADED CHECK OPTION
表示的就是更改的内容必须符合视图创建的条件,否则就会被阻挡,规则一致性。这个WITH CHECK OPTION 不仅会检查当前视图,还会检查所依赖的视图,如果最后一次基于基图生成的没有加限制条件即WITH CASCADED CHECK OPTION
就不会对这条语句进行限制效果,但是基图的限制依然存在
LOCAL: 使用with local chekck option;
只检查当前视图的条件,不会循环检查其他视图了,即对底层的限制条件不会关心不会约束
视图更新条件
视图的行与基础表的行之间必须存在一对一的关系。如果视图包含以下任何一项,则视图不可更新:
1.聚合函数或者窗口函数
2.DISTINCT
3.GROUP BY
4.HAVING
5.UNION 或者 UNION ALL
作用: 简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。
存储过程
循环结构Repeat——满足条件退出循环,但是会先执行一次
REPEAT SQL 逻辑 UNTL 条件
END REPEAT ; @n := 1
create procedure p8(in n int )
begin declare total int default 0 ; repeate set total := total +1 ;set n := n -1 ; until n<10 end repeate;
end ;
loop实现简单循环如果不添加退出条件就会一直循环:LEAVE——配合循环使用,退出循环(BREAK)。ITERATE——必须在循环中,作用时跳过当前循环剩下的语句,直接进入下一次循环(CONTINUE)。
create procedure p9(in n int)begin declare total int default 0 ;sum:loopif n <=0 then leave sum; set total = totalend if; if n %2 = 1 then set n := n -1;iterate sum; end if ;set n = n-1 ; end loop sum;select total end;
游标/光标
定义:用来存储查询结构集的数据类型,在存储过程和函数汇中可以使用游标对结果集进行循环处理。游标的使用包括游标的声明、OPEN、FETCH和CLOSE
DECLARE 游标名称 CURSOR FOR 查询语句;
定义游标
OPEN 游标名称
在使用游标之前就需要先打开游标
FETCH 游标名称 INTO 变量[变量];
获取游标记录
CLOSE 游标名称
关闭游标
注意:需要先申明普通变量再声明游标
create procedure p6(in age int )
begin declare uname varchar(10) ;declare uprofeesion varchar(10);declare u cursor for select name ,profession from tb_usr t where t.age < = age ;drop if exist tb_usr_pro;create table if exist tb_usr_pro(id int primary key auto_increment,name varchar(100) ,profession varchar(100));open u ;while true do fetch u into name,profession into uname uprofession;insert into tb_usr_pro values (nil ,uname,uprofession) end while;cloes u ;end while
end;
解决这个死循环的问题就要定义条件处理程序
DECLARE handler_action HANDLER FOR condition_value[,condition_value].... statement; handler_action CONTINUE : 继续执行当前程序 EXIT:终止执行当前程序 condition_valu SQLSTATE sqlstate_value:状态码SQLWARNING:所有01开头的SQLSTATE代码的简写 NOT DOUND:所有02开头的SQLSTATE代码 SQLEXCEPTION:所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE的代码简写 所以上面的可以这么定义:
declare exit handler for SQLSTATE ‘02000’ close u;--就相当于处理报错的,如果出现错误就会关闭游标
存储函数
存储函数是有返回值的存储过程,存储函数的参数只能是IN类型的
CREATE FUNCTION 存储函数名称([参数列表])
RETURN type [characteristic ....] #结果返回值 其中characteristic必须要加
BEGIN -SQL语句 RETURN .....;
END; charachteristic说明: DETERMINSTIC:相同的输入参数总是产生相同的结果 NO SQL: 不包含SQL语句 READS SQL DATA:包含读取数据的语句,但不包含写入数据的语句
具体案列
create function fun1(n int)
returns int determinstic
begindeclare total int default 0; while n>0 do set total := total +n; set n := n -1 ;end while ;return total ;
end;
触发器
是在执行一定的SQL语句之后就会触发相对应的操作类似AOP切面——但是这个只支持行级触发。
CREATE TRIGGER name
BEFORE/AFTER INSERT/UPDATE/DELETE
ON tbl_name FOR EACH ROW --行级触发器
BEGIN trigger_stmt; ##编辑逻辑实现
END;
SHOW TRIGGER
查看触发器
DROP TRIGGER [schema_name]trigger_name;
没有指定schema_name,默认为当前数据库
使用:new可以代替
create trigger tb_user_insert_trigger
after insert on tb_user for each row
begininsert into user_log(id,operation,operate_time,operare_id,operate_params) VALUES (nill,'insert',now(),new.id(),concat('插入的数据为:id=',new.id,',new.name,',phone=',new.phone))
end;
锁
锁是计算机协调多个进程和线程访问同一资源的机制。
全局锁
锁的是数据库中的所有表
使用全局锁就是对整个数据库实现实列加锁,加锁后整个实列就只处于只读状态,后续DML的写语句,DDL语句,以及更新操作的事务提交语句都将被阻塞
flush tables with read lock;
表示生成全局锁
unlock tables;
表示释放全局锁
表级锁
每次操作锁住整张表
锁定粒度大,发生锁冲突的概率最高,并发度最低。
分为三类:表锁、元数据锁、意向锁
表锁
表共享读锁
表独占写锁
加锁——local table 表名.... read/write
释放锁:unlock table tables/客户端断开连接
读锁:如果对一个表添加了读锁,那么只会阻塞其他用户的写操作。而不会阻塞其他用户的读取操作
写锁:如果以一个表添加了写锁,那么其他客户端就不能进行读取和写操作,只有当前添加的客户端可以进行读写操作
元数据锁:MDL加锁的过程是系统自动控制的,无需显式实用,在访问一张表的时候自动加上。MDL锁住要作用是维护表元数据的数据一致性,在表上有活动事务的时候,不可以对元数据进行写入操作,当对一张表进行增删改查的时候,加MDL读锁(共享);当对表结构进行变更操作的时候,加MDL写锁(排他)。
如:
表示的就是有兼容也有互斥的操作
意向锁:为了避免锁与锁的冲突即表锁与行锁的冲突,在InnoDB中引入了意向锁,使得表锁不用检查每行数据是否加锁,实用意向锁来减少表锁的检查。
意向共享锁(IS):有语句select … lock in share mode 添加,这个与read锁兼容,与write锁互斥
select * from score where id = 1 lock in share mdoe
添加了意向共享锁
意向排他锁(IX):由insert、update、delete、select … for update ,与read以及write都互相排斥
update score set name='里' where id = 1 ;
会默认添加一个意向排他锁即IX
行级锁
InnoDB的数据是基于索引组织的,行锁主要是针对索引上的索引项加锁实现的,而不是对记录加的锁。主要分为三类:
1.行锁:锁定单个行记录的锁,防止其他事务对次进行update 和delete
2.间隔锁:锁定索引记录的间隔,确保索引记录间隔不变方式其他事务在这个间隔进行insert操作产生幻读
3.临键锁:行锁和间隔锁组合,同时锁住数据,并锁住数据前面的间隔GAP
行锁
共享锁:允许一个事务去读一行,防止其他事务获得相同数据集的排他锁,都可以读取。
排他锁:允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。
查看锁的数据
select object_schema,object_name,index_name,lock_type, ,lock_data from performance_schema.data_lock;
InnoDB的行锁是针对索引加的锁,不通过索引条件检索数据,那么InnoBD 将对表中的所有记录加锁,此时就会升级为表锁
间隙锁
解决幻读显现
1.当对不存在的索引添加锁的时候就会是间隙锁,间隙锁锁的是两个行之间的数据,并不包含着两个
2.索引上的等值查询(普通索引),向右遍历时最后一个值不满足查询需求时,临间锁退化了间隔锁——锁住前后间隙和本身。
3.索引上的范围查询(唯一索引)–会访问到不满足条件的第一个值为止,即满足范围的所有都会锁住
InnoDB 引擎
逻辑存储结构
表空间:(ibd文件),一个mysql实列可以对应多个表空间,用于存储记录、索引等数据。
段:分为数据段、索引段、回滚段,InnoDB是索引组织表,数据段就是B+树的叶子节点,索引段即为B+树的非叶子节点,段用来管理多个区
区:表空间的单元结构,每个区的大小为1M。默认情况下,InnDB存储引擎页大小为16K,即一个区中一共有64个连续的页
页:是InnODB存储引擎的最小单元,每个页的大小默认为16KB。为了保证页的连续性,InnoDB存储引擎每次从磁盘申请4-5个区
行:InnoDB存储引擎数据是按行进行存放的。
架构
内存结构:
Buffer Pool:是计算机主内存的一块区域,里面存储经常操作的真实数据,在执行增删改查操作时,先操作缓冲池汇总的数据(若缓冲池中没有数据,则从磁盘上加载并缓冲),然后再以一定频率刷新到磁盘汇总,从而减少IO,加快处理速度。————缓冲池以page为单位,根据状态可以分为三种类型:1.free page:空闲页,未被使用 2.clean page:数据被使用,但没有修改 3.dirty page:脏页,被使用page,数据被修改过,也中数据与磁盘的数据产生了不一致
Change Buffer:更改缓冲区,在执行DML语句的时候如果数据没有缓存在Buffer Pool中他不会直接缓存数据而是先将操作指令放到Chage Buffer后面当对应数据放入Buffer Pool在进行相应修改
Adaptive Hash Index:自适应哈希索引,用于优化Buffer Pool数据查询。
Log Buffer :日志缓冲区,用来保存要写入到磁盘中的log日志数据(redo log、 undo log),默认大小为16MB,日志缓冲区会定期刷新到磁盘中。
磁盘结构
System Tablespace:系统表空间是更改缓冲区的存储区域。如果表是在系统表空间而不是每个表文件或通用表空间创建的,它也可能包含表的索引数据。
参数:innodb_date_file_path
File-Per-Table Tablespace:每个表的文件表空间包含单个InnoDB表的数据和索引,并存储在文件系统上的单个数据文件中。
General Tablespaces :通用表空间,需要通过CREATE TABLESPACE 语法创建通用表空间,从而让表的数据存放在指定的表空间中。
Undo Tablespace:撤销表空间
Temporary Tablespace:临时表空间
Doublewrite Buffer Files:双写缓冲区
Redo Log: 重做日志,用来事务的持久性,数据恢复。
后台线程
1.Master Thread:核心后台线程,负责将缓冲池中的数据异步刷新到磁盘中,保持数据的一致性。
2.IO Thread:采用的是AIO来处理IO请求。
3.Purge Thread:用于回收事务。
4.Page Cleaner Thread:协助脏页到磁盘的刷新
事务原理
事务的原子性、一致性、持久性的保障是由InnoDB中的日志保障的即redo.log 、 undo.log
隔离性是由锁机制、MVCC实现的
redo log: 重做日志,记录的是事务提交时数据页的无力修改,是用来实现事务的持久性。
该日志文件由两部分组成:重做日志缓冲以及重做日志文件,前者是在内存中,后者是在磁盘中。当事务提交之后会把所有修改信息都存放到该日志文件汇总,用于在刷新页面到磁盘,发生错误时,进行数据恢复使用。
脏页:就是在内存中已经更改了,但是磁盘中没有发生变化,所以需要将内存中的数据及时缓冲到磁盘中。
所以说redo_log是先将缓存中的操作经过redolog_buffer进行缓存然后写入磁盘中的ib_logfile0/1文件中从而实现了对应的刷新,这种是顺序磁盘IO,而直接修改页是属于随机磁盘IO效率低下。
undo log:回滚日志,用于记录数据被修改之前的信息。作用:提供回滚和MVCC(多版本并发控制)
undo_log的销毁——当undo_log在事务执行时产生,事务提交时,并不会立即删除undo_log,因为这些日志还可能用于MVCC
undo_log存储——undo_log采用段的方式进行管理和记录,存放在前面介绍的rollback segmanet回滚段中,内部包含1024个undo logsegment
MVCC
当前读:是指读取的是记录中的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对当前的记录进行加锁。
快找读:简单的select(不加锁)不会进行阻塞。
定义:MVCC,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为Mysql实现MVCC提供一个非阻塞读功能,实现需要依赖于数据库记录中的三个隐式字段、undolog日志、readView
实现原理
1.记录当中的隐藏字段
2.undo_log日志
不同事务或相同事务对同一条记录进行修改,会导致该记录的undolog生成一条记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。
隐藏字段中的回滚指针指向回滚日志(undo_log)。
3.readview
是快照读SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(为提交的)id。
RC隔离级别包含四个核心字段:
m_ids——当前活跃的事务ID集合——如果在这个里面就表示该事务id已经提交了,否则继续往下面找
min_trx_id——最小活跃事务ID
max_trx_id——预分配事务ID,当前最大事务ID+1
creator_trx_id——ReadView创建者的事务ID
RR隔离级别为:
直接复用同一个事物上的版本不会进行迭代,从而实现可重复读。
MySQL 管理
系统数据库:
mysql数据库——提供了系统数据库所运行的各种信息
information_schema——提供了访问数据库元数据的各种表和视图,包含了数据库、表、字段类型以及访问权限等
performance_schema——为Mysql服务器运行时状态提供一个底层监控功能,主要用于手机数据服务器性能参数
sys——为了方便DBA和相关人员调整参数
日志
错误日志
错误日志时MySQL 中最重要的日志之一,它记录了当mysql启动和停止时,以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时,查看此日志。
该日志默认开启存放在/var/log/,默认日志文件夹名为mysql.log。查看日志位置
show variavles like '%log_error%'
二进制日志
binlog
记录了所有DDL数据定义语言和DML数据操作语言。
作用:灾难时的数据恢复;MYSQL的主从复制
show variables like '%log_bin%'
然后binlog.index表示的就是索引文件
格式:STATRMRNT——基于SQL语句的日志记录,记录的是SQL语句
ROW——基于行的日志记录,记录的是每一行的数据变更
MIXED——混合了两种格式,默认使用STATEMENT,某种特殊情况下自动切换为ROW进行记录
mysqlbinlog [参考选项] logfilename- d 指定数据库名称,只列出指定的数据库相关操作 - o 忽略掉日志中的前n行命令 - v 将行事件重构为SQL语句,ROW中对应 - w 将行事件重构为SQL语句,并输出注释信息
reset master
删除全部binlog日志,删除后日志编号,将从binlog.00001重新开始
purge master logs to 'binlog.****'
删除*****编号之前的所有日志
purge master logs before 'yyyy-mm-dd hh 24:mi:ss'
表示删除日志为。。。时间段之前的所有日志
show variables like '%binlog_expire_logs_seconds%'
可以在mysql的配置文件中配置二进制日志的国旗时间,设置之后,二进制日志过期会自动删除——默认30天。
查询日志
查询日志只是记录了所有查询语句,默认情况开启。
更改里面的vim /etc/my.conf
慢查询日志
记录的就是所有执行时间超过参数long_query_time时间
slow_query_log = 1
表示开启慢查询
long_query_time = 2
执行时间参数
主从复制
概述
主库和从库,主从复制是指将主数据库的DDL和DML操作通过二进制日志传到从库服务器中,然后从库对这些日志重新执行(重做),从而使得从库和主库的数据保持同步。
MYSQL支持一台主库同时向多台从库进行复制,从库同时也可以作为其他从服务器的主库,实现链状复制
原理
所以是将二进制日志文件放到从库服务器中让他执行对应的二进制文件
1.MASTER主库在事务提交时候,会讲数据变更记录在二进制日志文件Binlog中。
2.从库读取主库的二进制日志文件Binlog,写入到从库中继日志的Relay log中。
3.slave重做中继日志的时间,将改变反映他自己的数据。
搭建
主库配置:
修改/etc/my.conf配置文件
#服务器ID
server-id=1
#是否只读,1代表只读,0代表写读
read-only=0#重起数据库
systemctl restart mysqld #创建账号并且赋予主从复制权限
CREATE USER 'aaa@%' IDENTIFIED WITH mysql_native_password BY 'ROOT@123456'; #密码为ROOT@123456
赋予用户权限
GRANT REPLICATION SLAVE ON *.* TO 'aaa'@'%'; show master status #查看二进制日志
从库:
修改/etc/my.cnf
#mysql服务ID,保证整个集群环境中唯一
server-id = 2
read-only = 1 # 登陆从库并且与主库设置对应的关系
CHANGE REOLICATION SOURCE TO SOURCE_HOST='xxxx.xxxx',SOURCE_USER='xxx',SOURCE_PASSWORD='xxx',SOURCE_LOG_FILE='xxx',SOURCE_LOG_POS=xxx;
如果是8.0.23版本之后
CHANGE MASTER TO MASTER_HOST=‘xxx.xxx.xxxx’,MASTER_USER='xxx',MASTER_LOG_FILE='xxx',MASTER_LOG_POS=xxx; FILE 对应的是二进制文件,POS对应的位置 start replicate; #启动
start slave ; #启动 show replicate status\G #查看主库的相关信息
这个是从二进制文件开始进行主从复制,所以之前需要先把主库的数据先同步到从库
分库分表
使单一数据库/表的数据量变小来缓解单一数据库的性能问题。
拆分策略:
垂直拆分:
垂直分库:以表为依据,根据业务不同将表拆分到不同库中。特点:每个库的表结构不同,数据不同,所有库的并集是全量数据
垂直分表:以字段为依据,根据字段属性,将不同字段拆分到不同表中。特点:每个表的结构不一样,每个表的数据不一样通过主键/外键关联,所有表的并集是全量数据
水平拆分:
水平分库:以字段为依据,按照一定策略,将一个库的数据拆分到多个库中。每个库的表结构一样,数据不一样,所有库的并集是全量数据。
水平分表:以字段为依据
Mycat
shardingJDBC:基于AOP原理,在应用程序中对本地执行的SQL进行拦截、解析、改写、路由处理。
MyCat:数据库分库分表的中间件,不用调整代码就可以实现分库分表。
MyCat
实现原理:伪装协议(mysql)
实现语言:JDK
配置/etc/profile文件中末尾添加如下配置
JAVA_HOME=/usr/local/jdkxxxx
PATH=$JAVA_HOME/bin:$PATH
在mycat中有:
BIN :存放可执行文件用于停止、启动MYCAT
conf:存放配置文件
LIB:存放依赖包
LOGS:存放日志文件
核心概念:
逻辑库中有多个逻辑表,逻辑表中存在多个分片节点中(根据分片规则存储)
在物理结构中的每个主机称为节点主机
综上MYCAT中不储存数据,只是对数据在逻辑上进行处理
关注当前的schema.xml配置文件
全局表:是指每一个库都有一个表格,并且该表格内的全局表所对应数据都是一致的,全局表的数据更新之后所有的全局表数据都更新
分片规则-范围:根据指定的字段及其配置的范围与数据节点的对应情况,来决定该数据属于哪一个分片
取模分片——通过取模运算
一致性hash——通过字段的hash值来,相同的哈希因子计算值总是被划分到相同的分区表中,不会因为分区节点的增加而改变原来数据的分区位置。
枚举——通过值将数据分配到不同的节点上,存在默认值。
应用指定——根据值的字符子串(数字)计算分片号。
固定分片hash算法——类似于十进制的求模运算,但是为二进制操作低10位与1111111111 进行位&运算,分片长度可以不一致。分片长度最大为1024
字符串hash解析——截取指定的子字符串,然后使用hash算法,算出分片
按天进行分片
按自然月进行分片
管理及监控功能
8066——数据访问端口,即进行DML和DDL操作
9066——数据库管理端口,即mycat服务管理控制功能,用于管理mycat的整个集群
读写分离
介绍:基于主从复制的基础(基于二进制binlong日志),相当于续写而不是覆盖
一主一从:从节点通过两个线程一边读取一别被其他调用
双主双从:一个主写一个一个备用