mysql高级篇笔记
mysql高级篇(一)mysql的安装配置、架构介绍及SQL语句的复习.
mysql高级篇(二)mysql索引优化分析.
mysql高级篇(三)查询截取分析(慢查询日志)、主从复制以及mycat的安装和使用.
文章目录
- 第七章查询截取分析
- 7.1慢查询日志
- 7.1.1是什么
- 7.1.2怎么用
- 7.1.3日志分析工具mysqldumpslow
- 7.2SHOW PROCESSLIST
- 第八章 工具和技巧拾遗(视图 VIEW)
- 第九章 主从复制
- 9.1 复制的基本原理
- 9.2 复制的基本原则
- 9.3复制的最大问题
- 9.4 一主一从常见配置
- 第十章MYCAT
- 10.1 是什么
- 10.2 做什么
- 10.3 MYCAT 原理
- 10.4 安装启动
- 10.5 读写分离
- 10.5.1 修改配置文件 schema.xml
- 10.5.2 balance
- 10.5.3验证读写分离
- 10.6 分库
- 10.6.1如何选择分库表
- 10.6.2 修改配置文件 schema.xml
- 10.7 水平分表
- 10.8 全局序列
- 10.8.1 本地文件
- 10.8.2 数据库方式(推荐)
- 10.8.3 时间戳方式
- 10.8.4 自主生成
第七章查询截取分析
7.1慢查询日志
7.1.1是什么
- (1)MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具 体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。
- (2)具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为 10,意思是运行10秒以上的语句。
- (3)由他来查看哪些SQL超出了我们的最大忍耐时间值,比如一条sql执行超过5秒钟,我们就算慢SQL,希望能 收集超过5秒的sql,结合之前explain进行全面分析。
- 记住,一般大公司里慢查询日志是由运维人员管理,开发人员需要找运维打开
7.1.2怎么用
- 默认情况下,MySQL数据库没有开启慢查询日志,需要我们手动来设置这个参数。
- 当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。慢查询日志支持将日志记录写入文件
- 开启设置
- 设定阈值
- 首先默认是十秒
- 自己设置秒数
-永久生效需要修改配置文件 my.cnf 中[mysqld]下配置,如下内容:
slow_query_log=1
slow_query_log_file=/var/lib/mysql/atguigu-slow.log
long_query_time=3
log_output=FILE
- 可以使用命令修改,也可以在my.cnf参数里面修改。
假如运行时间正好等于long_query_time的情况,并不会被记录下来。也就是说,
在mysql源码里是判断大于long_query_time,而非大于等于。
7.1.3日志分析工具mysqldumpslow
- 查看mysqldumpslow的帮助信息
7.2SHOW PROCESSLIST
7.2.1是什么
7.2.2 怎么用
- show processlist
- 杀死进程
- kill 进程id
第八章 工具和技巧拾遗(视图 VIEW)
8.1 是什么
- 将一段查询 sql 封装为一个虚拟的表。
- 这个虚拟表只保存了 sql 逻辑,不会保存任何查询结果。
8.2 作用
- (1)封装复杂 sql 语句,提高复用性
- (2)逻辑放在数据库上面,更新不需要发布程序,面对频繁的需求变更更灵活
第九章 主从复制
9.1 复制的基本原理
(1)slave 会从 master 读取 binlog 来进行数据同步,
并且它是从接入点开始复制
(2)三步骤+原理图
- MySQL 复制过程分成三步:
- master 将改变记录到二进制日志(binary log)。这些记录过程叫做二进制日志事件,binary log events;
- slave 将 master 的 binary log events 拷贝到它的中继日志(relay log);
- slave 重做中继日志中的事件,将改变应用到自己的数据库中。 MySQL 复制是异步的且串行化的
9.2 复制的基本原则
- (1)每个 slave 只有一个 master
- (2)每个 slave 只能有一个唯一的服务器 ID
- (3)每个 master 可以有多个 salve
9.3复制的最大问题
9.4 一主一从常见配置
- (1) mysql 版本一致且后台以服务运行
- (2) 主从都配置在[mysqld]结点下,都是小写
- (3)主机修改 my.ini 配置文件(记得备份一下,我的备份也在D盘的mysql下)
- 主服务器唯一 ID :
- 启用二进制日志:
- log-bin=自己本地的路径/data/mysqlbin
- log-bin=D:/devSoft/MySQLServer5.7/data/mysqlbin (这是我的本地路径,就到data,最后一个是文件)
- 设置不要复制的数据库:
- 设置需要复制的数据库:
- binlog-do-db=需要复制的主数据库名字(这个库切记不能建)
- 设置 logbin 格式
- binlog_format=STATEMENT(默认)
- logbin 格式:
- binlog_format=STATEMENT(默认)
- 会在binlog日志中记录所有写操作的SQL
- 但是缺点是假设在主机里写了一个函数语句,等延时后从机复制,会发现主从复制不一致,这也是问题所在
- binlog_format=ROW
- 行模式,不在binlog日志中执行写操作了,而是记执行完SQL每一行的改变,
- 但是效率太低
- binlog_format=MIXED
- 此模式是来回切换,如果发现SQL语句没有函数,那就用statement(默认)模式,如果有函数则切换为row模式,来回切换
- 但是这样也有问题,当出现系统变量时,也会出现主从复制不一致问题
- (4)从机配置文件修改my.cnf的[mysqld]栏位下
- 记得先备份一下,我的在etc目录(同目录)下备份为my.cnfback
该重要文件一定要提前备份
- #从机服务 id ()
- #设置中继日志
- (5) 因修改过配置文件,请主机+从机都重启后台 mysql 服务
- windows重启mysql
- Linux重启mysql
- (6) 主机从机都关闭防火墙、安全工具(腾讯管家等)
- windows手动关闭
- 关闭虚拟机linux防火墙 systemctl stop firewalld
- (7) 在 Windows 主机上建立帐户并授权 slave
- GRANT REPLICATION SLAVE ON . TO ‘备份账号’@‘从机器数据库 IP’ IDENTIFIED BY ‘密码’;
- 在mysql库的user表中查看创建的用户
- (8) 查询 master 的状态,并记录下 File 和 Position 的值
- #查询 master 的状态 show master status;
- 执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化
- (9) 在 Linux 从机上配置需要复制的主机
- CHANGE MASTER TO MASTER_HOST=‘主机ip地址’,
MASTER_USER=‘创建用户名’,
MASTER_PASSWORD=‘创建的密码’,
MASTER_LOG_FILE=‘mysqlbin.具体数字’,MASTER_LOG_POS=接入点具体值;
- (10) 启动从服务器复制功能
- start slave;
- 查看主从复制的状态show slave status\G;
- 两个参数都是 Yes,则说明主从配置成功!
- (11) 主机新建库、新建表、insert 记录,从机复制
- (12) 如何停止从服务复制功能 stop slove;
- (13)如何重新配置主从
- stop slave;
reset master;
第十章MYCAT
10.1 是什么
- 1、一个彻底开源的,面向企业应用开发的大数据库集群
- 2、支持事务、ACID、可以替代MySQL的加强版数据库
- 3、一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
- 4、一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
- 5、结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
- 6、一个新颖的数据库中间件产品
- 一端连接数据库,一端连接java程序
10.2 做什么
- 能满足数据库数据大量存储;提高了查询性能
- (1) 读写分离
- (2) 数据分片:
- 垂直拆分(分库)
- 水平拆分 (分表)
- 垂直+水平拆分
- (3) 多数据源整合
10.3 MYCAT 原理
- “拦截”:Mycat 的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的 SQL 语句,首先对 SQL 语 句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此 SQL 发往后端的真实数 据库,并将返回的结果做适当的处理,最终再返回给用户。
- 这种方式把数据库的分布式从代码中解耦出来,程序员察觉不出来后台使用 mycat 还是 mysql。
10.4 安装启动
-
将下载好的mycat安装包传到Linux的opt目录下
-
使用此命令tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz 解压得到mycat文件夹,如图:
-
至此准备工作做完,下面开始安装启动:
-
(1) 解压缩文件拷贝到 linux 下 /usr/local/
-
-
(2) 三个配置文件
- schema.xml 定义逻辑库,表、分片节点等内容
- rule.xml 定义分片规则
- server.xml 定义用户以及系统相关变量,如端口等
-
(3) 启动前先修改 schema.xml
- 输入命令set nu 显示行号
- 删除6到32行(一般模式下dd是删除一行,d n d 从标签处开始删除n行)
- 在schema标签里添加 dataNode=“dn1”
- 设置数据节点 dataNode
- 设置写主机和读主机
-
schema.xml文件的标签介绍:
- 1.Schema:逻辑库,与MySQL中的Database(数据库)对应,一个逻辑库中定义了所包括的Table。
- 2.Table:逻辑表,即物理数据库中存储的某一张表,与传统数据库不同,这里的表格需要声明其所存储的逻辑数据节点DataNode。在此可以指定表的分片规则
- 3.DataNode:MyCAT的逻辑数据节点,是存放table的具体物理节点,也称之为分片节点,通过DataSource来关联到后端某个具体数据库上
- 4.DataSource:定义某个物理库的访问地址,用于捆绑到Datanode上
- 5、分片规则:前面讲了数据切分,一个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难
-
(4)再修改server.xml
<user name="mycat">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
</user>
- (5) 验证数据库访问情况
- 访问主机库出错
- 这是因为Windows下的mysql的没用远程操作的root用户,可用下面命令添加相关用户
grant all privileges on *.* to root@'%' identified by '123456';
-
-
- (6)启动程序
- 控制台启动 :去 mycat/bin 目录下 ./mycat console
- 后台启动 :去 mycat/bin 目录下 ./mycat start
- (7)启动时可能出现报错
- 域名解析失败,解决方法:
- 1、用vim 修改 /etc/hosts 文件
- 2、修改后重新启动网络服务
- (8)登录
- 后台管理窗口登录:
- mysql -u 用户名(mycat) -p 密码 -P9066 -h 主机 ip
- 数据窗口登录:
- mysql -u 用户名(mycat) -p 密码 -P8066 -h 主机 ip
- show databases
10.5 读写分离
10.5.1 修改配置文件 schema.xml
balance设为2 ,两台机器随机读,效果如下:
10.5.2 balance
- balance=“0”, 不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上。
- balance=“1”,全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备),正常情况下,M2,S1,S2 都参与 select 语句的负载均衡。
- balance=“2”,所有读操作都随机的在 writeHost、readhost 上分发。
- balance=“3”,所有读请求随机的分发到 readhost 执行,writerHost 不负担读压力
10.5.3验证读写分离
create table t_replica (id int, name varchar(200));
insert into t_replica values (1,@@hostname);
- 这是Windows主机名
- 这是Linux的主机名:
- 然后再mycat下执行select * from t_replica能够分辨mycat访问的是哪台机器
- 惊讶的发现访问的是Windows机器,没有读写分离,这是因为schema.xml文件中的balance没设置,看上面介绍balance
10.6 分库
10.6.1如何选择分库表
CREATE TABLE customer(
id INT AUTO_INCREMENT,
NAME VARCHAR(200),
PRIMARY KEY(id)
);
CREATE TABLE orders(
id INT AUTO_INCREMENT,
order_type INT,
customer_id INT,
amount DECIMAL(10,2),
PRIMARY KEY(id)
);
CREATE TABLE orders_detail(
id INT AUTO_INCREMENT,
detail VARCHAR(2000),
order_id INT,
PRIMARY KEY(id)
);
CREATE TABLE dict_order_type(
id INT AUTO_INCREMENT,
order_type VARCHAR(200),
PRIMARY KEY(id)
);
- 下面配置文件用到了新的数据库,记得启动mycat之前建好
- 按照下面配置好之后,这四个表就分库存放了,customer放在dn2,Windows机器下的数据库,其他三个放在Linux下的数据库
10.6.2 修改配置文件 schema.xml
10.7 水平分表
- (1) 修改配置文件 schema.xml
- (2) 修改配置文件 rule.xml
- MYCAT常用的分片规则如下:
(1)分片枚举: sharding-by-intfile
(2)主键范围约定: auto-sharding-long 此分片适用于,提前规划好分片字段某个范围属于哪个分片
(3)一致性hash: sharding-by-murmur
(4)字符串hash解析: sharding-by-stringhash
(5)按日期(天)分片:sharding-by-date
(6)按单月小时拆分: sharding-by-hour
(7)自然月分片: sharding-by-month
(8)取模: mod-long 此规则为对分片字段求摸运算
(9)取模范围约束: sharding-by-pattern 此种规则是取模运算与范围约束的结合,主要为了后续数据迁移做准备,即可以自主决定取模后数据的节点分布
-
(3) 跨库 join ER 表
- 为了相关联的表的行尽量分在一个库下
-
(4) 全局表
- 设定为全局的表,会直接复制给每个数据库一份,所有写操作也会同步给多个库。 所以全局表一般不能是大数据表或者更新频繁的表。一般是字典表或者系统表为宜。
10.8 全局序列
10.8.1 本地文件
10.8.2 数据库方式(推荐)
- (1) 数据库序列方式原理
- 利用数据库一个表 来进行计数累加。但是并不是每次生成序列都读写数据库,这样效率太低。 mycat 会预加载一部分号段到 mycat 的内存中,这样大部分读写序列都是在内存中完成的。如果内存中的号 段用完了 mycat 会再向数据库要一次。 如果 mycat 崩溃了 ,内存中的序列都没了,那么 mycat 启动后会向数据库申请新的号段,原有号段会弃用。 也就是说如果 mycat 重启,那么损失是当前的号段没用完的号码,但是不会因此出现主键重复。
- (2) 建库序列脚本
表
CREATE TABLE MYCAT_SEQUENCE (NAME VARCHAR(50) NOT NULL,current_value INT NOT
NULL,increment INT NOT NULL DEFAULT 100, PRIMARY KEY(NAME)) ENGINE=INNODB;
创建三个函数:
DELIMITER $$
CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50)) RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
DECLARE retval VARCHAR(64);
SET retval="-999999999,null";
SELECT CONCAT(CAST(current_value AS CHAR),",",CAST(increment AS CHAR)) INTO retval FROM
MYCAT_SEQUENCE WHERE NAME = seq_name;
RETURN retval;
END $$
DELIMITER;
DELIMITER $$
CREATE FUNCTION mycat_seq_setval(seq_name VARCHAR(50),VALUE INTEGER) RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = VALUE
WHERE NAME = seq_name;
RETURN mycat_seq_currval(seq_name);
END $$
DELIMITER ;
DELIMITER $$
CREATE FUNCTION mycat_seq_nextval(seq_name VARCHAR(50)) RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = current_value + increment WHERE NAME = seq_name;
RETURN mycat_seq_currval(seq_name);
END $$
DELIMITER;
查看序列
SELECT * FROM MYCAT_SEQUENCE
如果有就删除:
TRUNCATE TABLE MYCAT_SEQUENCE
这样全局序列是空的,于是初始化:
增加要用的序列
INSERT INTO MYCAT_SEQUENCE(NAME,current_value,increment) VALUES (‘ORDERS’, 400000,
100);
这样序列脚本就准备好了
- (3) 修改 mycat 配置
- sequence_db_conf.properties
- 意思是 ORDERS 这个序列在 dn1 这个节点上,具体 dn1 节点是哪台机子,请参考 schema.xml
- (4) 修改 mycat 配置 server.xml
- 重启mycat
10.8.3 时间戳方式
10.8.4 自主生成
- (1) 根据业务逻辑组合
- (2) 可以利用 redis 的单线程原子性 incr 来生成序列