1.单机优化
1.1.表结构设计
1.1.1.范式(规范)
什么样的表才是符合3NF (范式)
表的范式,是首先符合1NF, 才能满足2NF , 进一步满足3NF
1)1NF
1NF: 即表的列的具有原子性,不可再分解,即列的信息,不能分解.只要数据库是关系型数据库(mysql/oracle/db2/sysbase/sql server),就自动的满足1NF.关系型数据库中是不允许分割列的。
2)2NF
2NF:表中的记录是唯一的.通常我们设计一个主键来实现
3)3NF
即表中不要有冗余数据, 就是说,表的信息,如果能够被推导出来,就不应该单独的设计一个字段来存放.举例说明不满足:学生、班级
4)反3NF
反3NF :没有冗余的数据库表未必是最好的数据库表,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据 。具体做法是: 在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余。
举例说明:相册
相册是浏览次数是相片点击次数之和。
为了提高效率,直接在相册表添加浏览数。方便查询!
Pss:订单(订单明细集合 总价),订单明细(货品名称 货品数量 单价 总价)
1.1.2.存储引擎
分类:mysql:myisam,innodb,memory
1)优缺点
问 MyISAM 和 INNODB的区别(主要)******
INNODB存储引擎:
对事务要求高,保存的数据都是重要数据,我们建议使用INNODB,比如订单表,账号表.
Memory 存储
比如我们数据变化频繁,不需要入库,同时又频繁的查询和修改,我们考虑使用memory, 速度极快.
3)操作
1、创建表时指定存储引擎
Create table 表名(字段列表) engine 存储引擎名称;
注意:如果不指定则使用默认的存储引擎,这个默认实在my.ini配置
2、修改存储引擎:
alter table table_name engine=innodb;
1.2.索引
1.2.1.引入
说起提高数据库性能,索引是最物美价廉的东西了。不用加内存,不用改程序,不用调sql,只要执行个正确的‘create index’,查询速度就可能提高百倍千倍,这可真有诱惑力。可是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的,这些写操作,增加了大量的I/O。
1.2.2.什么是索引-原理
索引(Index)是帮助DBMS高效获取数据的数据结构。
1)生活中例子
2)索引
3)索引算法
Mysql常用引擎允许的索引类型
FullText全文索引算法,myisam,只能能在char vachar text
hash就像Map,通过一个key直接就能找到value
B-tree算法
4)小结
总结:使用索引把全表查找变为索引查找,减少查询次数,增加查询效率。而索引查找效率的取决于索引算法。也就是索引(Index)是帮助DBMS高效获取数据的数据结构
1.2.3.操作
mysql中索引的分类:
普通索引:允许重复的值出现,可以再任何字段上面添加
唯一索引:除了不能有重复的记录外,其它和普通索引一样,可以在值是唯一的字段添加(用户名、手机号码、身份证、email,QQ),可以为null,并且可以有多个null
主键索引:是随着设定主键而创建的,也就是把某个列设为主键的时候,数据库就会給改列创建索引。这就是主键索引.唯一且没有null值
全文索引:用来对表中的文本域(char,varchar,text)进行索引, 全文索引针对MyISAM有用
1)添加
分类:普通索引/唯一索引/主键索引/全文索引
普通索引:允许重复的值出现
一般来说,普通索引的创建,是先创建表,然后在创建普通索引
create index 索引名 on 表 (列1,列名2,…);
alter table 表名add index 索引名(列1,列名2,…);
比如:
create table aaa(id int unsigned,name varchar(32));
create index nameIndex on aaa(name);
alter table aaa add index index1(name);
唯一索引:除了不能有重复的记录外,其它和普通索引一样
1、当表的某列被指定为unique约束时,这列就是一个唯一索引
例如:create table bbb(id int primary key auto_increment , name varchar(32) unique);
这时, name 列就是一个唯一索引.
2、在创建表后,再去创建唯一索引
create unique index 索引名 on 表名 (列1,列2,…);
alter table 表名add unique index 索引名 (列1,列2,…);
例如:
create table ccc(id int primary key auto_increment, name varchar(32));
注意:unique字段可以为NULL,并可以有多NULL, 但是如果是具体内容,则不能重复.
主键字段,不能为NULL,也不能重复.
主键索引:是随着设定主键而创建的,也就是把某个列设为主键的时候,数据库就会給改列创建索引。这就是主键索引.唯一且没有null值
1、创建表时指定主键
例如:create table ddd(id int unsigned primary key auto_increment ,name varchar(32) not null defaul ‘’);
这时id 列就是主键索引.
2、如果你创建表时,没有指定主键,也可以在创建表后,再添加主键。
指令:alter table 表名 add primary key (列名);
举例: create table eee(id int , name varchar(32) not null default ‘’);
alter table eee add primary key (id);
全文索引:用来对表中的文本域(char,varchar,text)进行索引, 全文索引针对MyISAM有用
1、创建表时定义:
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
)engine=myisam charset utf8;
INSERT INTO articles (title,body) VALUES
(‘MySQL Tutorial’,‘DBMS stands for DataBase …’),
(‘How To Use MySQL Well’,‘After you went through a …’),
(‘Optimizing MySQL’,‘In this tutorial we will show …’),
(‘1001 MySQL Tricks’,‘1. Never run mysqld as root. 2. …’),
(‘MySQL vs. YourSQL’,‘In the following database comparison …’),
(‘MySQL Security’,‘When configured properly, MySQL …’);
创建表完成后定义
create fulltext index 索引名 on 表名(列1,列2);
alter table 表名add fulltext index 索引名 (列1,列2);
比如:
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT
)engine=myisam charset utf8;
Alter table article add fulltext index title_body_fulltext_index(title,body);
INSERT INTO articles (title,body) VALUES
('MySQL Tutorial','DBMS stands for DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
用法:
错误用法:
explain select * from articles where body like ‘%mysql%’; 【不会使用到全文索引】
正确用法::
explain select * from articles where match(title,body) against(‘database’);【会使用全文索引】
2) 查询
show index(es) from 表名
3) 删除
alter table 表名 drop index 索引名;
alter table 表名 drop primary key 删除主键。 [主键定义为auto_increment时不能删除]
4) 修改
先删除后添加=修改
1.2.4.注意事项
索引的代价:
1.占用磁盘空间。
2.对dml(增删该)操作有影响,因为要维护索引,变慢。
在哪些列上适合添加索引?
较频繁的作为查询条件字段应该创建索引
select * from emp where empno = 1
唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件
select * from emp where sex = '男’
更新非常频繁的字段不适合创建索引
select * from emp where logincount = 1
总结: 满足以下条件的字段,才应该创建索引.
a: 肯定在where条件经常使用
b: 该字段的内容不是唯一的几个值(sex)
c: 字段内容不是频繁变化.
不会出现在WHERE子句中字段不该创建索引
主键肯定要,唯一字段如果经常查询很少修改也要创建
1.2.5.小技巧
根据索引列的多少分为复合索引和普通索引
普通索引(单列索引):该索引只在一个列上面创建
复合索引(多列索引):该索引只在多个列上面创建
1)对于创建的多列索引(复合索引),不是使用的第一部分就不会使用索引。
alter table dept add index my_ind (dname,loc); // dname 左边的列,loc就是 右边的列
explain select * from dept where dname=‘aaa’ 会使用到索引
explain select * from dept where loc=‘aaa’ 就不会使用到索引
2. 对于使用like的查询,查询如果是%aaa’不会使用到索引而‘aaa%’会使用到索引。
explain select * from dept where dname like ‘%aaa’\G不能使用索引
explain select * from dept where dname like ‘aaa%’\G使用索引.
所以在like查询时,‘关键字’的最前面不能使用 % 或者 _这样的字符.,如果一定要前面有变化的值,则考虑使用 全文索引->sphinx.
3.如果条件中有or,有条件没有使用索引,即使其中有条件带索引也不会使用。换言之,就是要求使用的所有字段,都必须单独使用时能使用索引.
explain select * from dept where dname = ‘aaa’;
explain select * from dept where loc = ‘aaa’;
select * from dept where dname=’xxx’ or loc=’xx’;
4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引。
expain select * from dept where dname=’111’;
expain select * from dept where dname=111;(数值自动转字符串)
expain select * from dept where dname=qqq;报错
也就是,如果列是字符串类型,无论是不是字符串数字就一定要用 ‘’ 把它包括起来.
5.如果mysql估计使用全表扫描要比使用索引快,则不使用索引。
表里面只有一条记录
2.3.分表
分为水平分割(行)和垂直分割(列)
2.3.1.水平分表
一张表的数据太多时候要分表
如果一个表的记录数太多了,比如上千万条,而且需要经常检索,那么我们就有必要化整为零了。
如果我拆成100个表,那么每个表只有10万条记录。
当然这需要数据在逻辑上可以划分。一个好的划分依据,有利于程序的简单实现,也可以充分利用水平分表的优势。
比如系统界面上只提供按月查询的功能,那么把表按月拆分成12个,每个查询只查询
一个表就够了。如果非要按照地域来分,即使把表拆的再小,查询还是要联合所有表来
查,还不如不拆了。
所以一个好的拆分依据是最重要的。UNION,UNION ALL
例子: 用户表
原始方案:
分表方案
当用户注册用户,就自动分表.根据某个规则,把对应的用户放入对应表中.在查询时,还是根据这个规则,到对应的表中取出数据.
如果一张表中数据量巨大时,我们要经常查询。则可以按照合适的策略拆分为多张小表。尽量在单张表中查询,减少扫描次数,增加查询效率。如果拆分不好,经常组合查询,还不如不拆分.
分表策略
1.按时间分表
order_2017 order_2018 …
这种分表方式有一定的局限性,当数据有较强的实效性,如微博发送记录、微信消息记录等,这种数据很少有用户会查询几个月前的数据,如就可以按月分表。
2.按区间范围分表
一般在有严格的自增id需求上,如按照user_id水平分表:
table_1 user_id从1~100w
table_2 user_id从100w+1~200w
table_3 user_id从200W+1~300w
3.hash(Map)分表
通过一个原始目标的ID或者名称通过一定的hash算法计算出数据存储表的表名,然后访问相应的表。
最简单hash算法:t_user+id%100+1
一致性hash算法:
2.3.2.垂直分表
有些表记录数并不多,可能也就2、3万条,但是列的数量很多或者字段却很大,表占用空间很大,检索表时需要执行大量I/O,严重降低了性能。这个时候需要把大的字段拆分到另一个表,并且该表与原表是一对一的关系(外键)。 (JOIN)
例子:高考答题设计
原始设计:
分表设计
如果一张表某个字段,信息量大,但是我们很少查询,则可以考虑把这些字段,单独的放入到一张表中,通过外键关联。如果硬是要查询,就是用跨表查询(join)
分库:中间件(mysqlproxy、mycat)
2.4.分区
2.4.1.什么是分区
不同在于分表将大表分解为若干个独立的实体表,而分区是将数据分段划分在多个位置存放,可以是同一块磁盘也可以在不同的机器。分区后,表面上还是一张表,但数据散列到多个位置了。app读写的时候操作的还是大表名字,db自动去组织分区的数据。
查看数据库是否支持
SHOW VARIABLES LIKE ‘%partition%’;
数据非常多
2.4.2.分区作用
从MySQL 5.1 中新增了分区(Partition)功能,优势也越来越明显了:
–与单个磁盘或文件系统分区相比,可以存储更多的数据
–很容易就能删除不用或者过时的数据-以分区为单位来进行操作
–一些查询可以得到极大的优化 可以并发查询
–涉及到 SUM()/COUNT() 等聚合函数时,可以并发进行
–IO吞吐量更大
2.4.3.分区方式
常见分区方式:
Range(范围) –基于一个给定的连续空间,把数据分配到不同分区。1-10 11-20
List(预定义列表) –类似Range分区,区别在List分区是基于枚举出的值列表分区,而 Range分区是根据给定的连续区间范围分区 1,2,3 4,5,6
Hash(哈希)–这中模式允许通过对表的一个或多个列的Hash Key进行计算,最后通过这个Hash码不同数值对应的数据区域进行分区。例如可以建立一个对表主键进行分区的表。这个根据给定的分区个数,把数据分配到不同的分区。
Key(键值)-上面Hash模式的一种延伸,这里的Hash Key是MySQL系统产生的。
Composite(复合模式) –以上模式的组合使用
1.RANGE分区
基于属于一个给定连续区间的列值,把多行分配给分区。这些区间要连续且不能相互重叠,使用VALUES LESS THAN操作符来进行定义。以下是实例。
CREATE TABLE employees (
id INT NOT NULL,
name VARCHAR(30),
hired DATE NOT NULL DEFAULT ‘2015-12-01’,
job VARCHAR(30) NOT NULL,
dept_id INT NOT NULL
) engine myisam
partition BY RANGE (dept_id) (
partition p0 VALUES LESS THAN (6),-- 1-5
partition p1 VALUES LESS THAN (11),-- 6-10
partition p2 VALUES LESS THAN (16),-- 11-15
partition p3 VALUES LESS THAN (21)
);
insert into employees values(1,‘zs’,‘2015-12-10’,‘market’,15);
查询information_schema.partitions
RANGE分区在如下场合特别有用:
1)、 当需要删除一个分区上的“旧的”数据时,只删除分区即可。如果你使用上面最近的那个例子给出的分区方案,你只需简单地使用 “ALTER TABLE employees DROP PARTITION p0;”来删除所有在1991年前就已经停止工作的雇员相对应的所有行。对于有大量行的表,这比运行一个如“DELETE FROM employees WHERE YEAR (separated) <= 1990;”这样的一个DELETE查询要有效得多。
2)、想要使用一个包含有日期或时间值,或包含有从一些其他级数开始增长的值的列。
3)、经常运行直接依赖于用于分割表的列的查询。例如,当执行一个如“SELECT COUNT(*) FROM employees WHERE YEAR(separated) = 2000 GROUP BY dept_id;”这样的查询时,MySQL可以很迅速地确定只有分区p2需要扫描,这是因为余下的分区不可能包含有符合该WHERE子句的任何记录。
注释:这种优化还没有在MySQL 5.1源程序中启用,但是,有关工作正在进行中。
2、LIST分区
类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。
LIST分区通过使用“PARTITION BY LIST(expr)”来实现,其中“expr” 是某列值或一个基于某个列值、并返回一个整数值的表达式,然后通过“VALUES IN (value_list)”的方式来定义每个分区,其中“value_list”是一个通过逗号分隔的整数列表。
青羊区 3, 5, 6, 17
金牛区 1, 10, 11, 19
成华区 4, 12, 14, 18
锦江区 2, 9, 13, 16
高薪区 7, 8, 15, 20
CREATE TABLE employees (
id INT NOT NULL,
name VARCHAR(30),
hired DATE NOT NULL DEFAULT ‘2015-12-10’,
job_code INT,
store_id INT
)
PARTITION BY LIST(store_id)(
PARTITION pQY VALUES IN (3, 5, 6, 17),
PARTITION pJN VALUES IN (1, 10, 11, 19),
PARTITION pCH VALUES IN (4, 12, 14, 18),
PARTITION pJJ VALUES IN (2, 9, 13, 16),
PARTITION pGX VALUES IN ( 7, 8, 15, 20)
);
这使得在表中增加或删除指定地区的雇员记录变得容易起来。例如,假定西区的所有音像店都卖给了其他公司。那么与在成华区咖啡店工作雇员相关的所有记录(行)
可以使用查询“ALTER TABLE employees DROP PARTITION pCH;”来进行删除,
它与具有同样作用的DELETE (删除)查询“DELETE query DELETE FROM employees WHERE store_id IN (4,12,13,14,18);”比起来,要有效得多。
3、HASH分区
基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。
主要用来分散热点读,确保数据在预先确定个数的分区中尽可能平均分布。
CREATE TABLE employees (
id INT NOT NULL,
name VARCHAR(30),
hired DATE NOT NULL DEFAULT ‘2015-12-10’,
job_code INT,
store_id INT
)
PARTITION BY HASH(store_id)
PARTITIONS 4
MySQL还支持"线性哈希"功能,它与常规哈希的区别在于,
常规 哈希使用的是求哈希函数值的模数。缺点在于分区增加时的重新计算。
而线性哈希功能使用的一个线性的2的幂(powers-of-two)运算法则。
区别
线性哈希分区和常规哈希分区在语法上的唯一区别在于,在“PARTITION BY” 子句中添加“LINEAR”关键字。
PARTITION BY LINEAR HASH(YEAR(hired))
线性哈希分区的优点在于增加、删除、合并和拆分分区将变得更加快捷,有利于处理含有极其大量数据的表。它的缺点在于,与使用
常规HASH分区得到的数据分布相比,各个分区间数据的分布不大可能均衡。
4.KSY分区
类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL 服务器提供其自身的哈希函数。(表达式已经确定)必须有一列或多列包含整数值。
复制代码 代码如下:
CREATE TABLE employees (
id INT NOT NULL,
name VARCHAR(30),
hired DATE NOT NULL DEFAULT ‘2015-12-01’,
job VARCHAR(30) NOT NULL,
dept_id INT NOT NULL
)
partition BY KEY (job)
PARTITIONS 3;
与key不同在于key的值可以为空,但是要注意:
1) 可以不指定值,默认以主键为准
2) 如果没主键,以唯一键为准
3) 如果没主键,以唯一键为准,唯一键必须非空
4) 无主无唯一,就必须手动指定
在KEY分区中使用关键字LINEAR和在HASH分区中使用具有同样的作用,分区的编号是通过2的幂(powers-of-two)算法得到,而不是通过模数算法。
分区空值处理:
1、range方式,默认放入最小值分区
2、list方式,必须指定null值匹配
3、hash方式,默认当成0
4.5.SQL优化小技巧
4.5.1.DDL优化
1 、通过禁用索引来提高导入数据性能 。 这个操作主要针对有数据库的表,追加数据
//去除键
alter table test3 DISABLE keys;
//批量插入数据
insert into test3 select * from test;
//恢复键
alter table test3 ENABLE keys;
变多次索引维护为一次维护
2、 关闭唯一校验
set unique_checks=0 关闭
//批量插入数据
insert into test3 select * from test;
set unique_checks=1 开启
变多次唯一校验为一次校验
3、修改事务提交方式(导入)
set autocommit=0 关闭
//批量插入
set autocommit=1 开启
变多次事务提交为一次事务提交
4.5.2.DML优化
insert into test values(1,2);
insert into test values(1,3);
insert into test values(1,4);
//合并多条为一条
insert into test values(1,2),(1,3),(1,4)
变多次事务提交为一次事务提交
4.5.3.DQL优化(了解)
1)1 order by优化
1、多用索引排序
2、普通结果排序(非索引排序)Filesort
索引本身就是排序的,所以多使用索引。
2)group by优化
查询某个时间的付款总和
explain
select DATE_FORMAT(payment_date,’%Y-%m’),sum(amount) from payment GROUP BY DATE_FORMAT(payment_date,’%Y-%m’) ;
explain
select DATE_FORMAT(payment_date,’%Y-%m’),sum(amount) from payment GROUP BY DATE_FORMAT(payment_date,’%Y-%m’) order by null;
在group by是使用order by null,取消默认排序
3) subQuery嵌套优化(子查询)
在客户列表找到不在支付列表的客户
#在客户列表找到不在“支付列表”的客户 , 查询没买过东西的客户
explain
select * from customer where customer_id not in (select DISTINCT customer_id from payment); #子查询 – 这种是基于func外链
explain
select * from customer c left join payment p on(c.customer_id=p.customer_id) where p.customer_id is null – 这种是基于“索引”外链
4)or优化
在两个独立索引上使用or的性能优于
1、 or两边都是用索引字段做判断,性能好!!
2、 or两边,有一边不用,性能差
3、 如果employee表的name和email这两列是一个复合索引,但是如果是 :name=‘A’ OR email=‘B’ 这种方式,不会用到索引!
5)limit优化
select film_id,description from film order by title limit 50,5;
select a.film_id,a.description from film a inner join (select film_id from film order by title limit 50,5)b on a.film_id=b.film_id
1、为什么需要读写分离?
一台服务器满足不了访问需要。
数据的访问基本都是2-8原则。
2、怎么做?
不往从服务器去写了,那就要主上写的操作都要同步到从(主从同步)
(1) master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,
binary log events);
(2) slave将master的binary log events拷贝到它的中继日志(relay log);
(3) slave重做中继日志中的事件,将更改应用到自己的数据上。
把读的请求同步到从,把写的请求分发的主。(读写分离) 技术选型,mysql proxy
5.2.读写分离
5.2.1.准备环境
1)分别构造主、从数据库并输出日志(方便定位问题)
拷贝
改端口
拷贝数据
拷贝原理数据库的data.dir mysql到模拟的主从数据库
配置日志路径
2)安装及启动:
mysqld --install MySQL_master --defaults-file=“C:\Program Files (x86)\MySQL\master\my.ini”
net start MySQLXY
测试
5.2.2.master服务器配置
1)修改master方的my.ini
[mysqld] (一定在文件要末尾追加)
log-bin=mysql-bin
server-id=1
2)重启master服务,登录
3)授权slave服务器的使用的账号及权限
场景:
master主服务器: 172.16.6.254:3307
slave从服务器 : 172.16.6.254:3308
1) 授权给slave数据库服务器192.168.10.131(master用户,只对slave服务器开放)
语法为:GRANT REPLICATION SLAVE ON . to ‘用户名’@‘192.168.0.102’ identified
by ‘密码’;
Mysql> GRANT REPLICATION SLAVE ON . to ‘slave’@’%’ identified by ‘slave’;
FLUSH PRIVILEGES; – 刷新权限
参数说明:
yhptest:slave连接master使用的账号
IDENTIFIED BY ‘admin’ :slave连接master使用的密码
192.168.77.128:slave IP
2)查询主数据库状态
Mysql> show master status;
+--------------------+----------+---------------+------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+---------------+------------------------------+
| mysql-bin.000002 | 226 | | mysql |
+--------------------+----------+---------------+------------------------------+
记录 File 和 Position的值,在slave端使用
mysql-bin.000001 107
5.2.3.从数据库
1、修改slave服务器的配置文件my.ini将
2、server-id = 1修改为 server-id = 2,并确保这个
ID没有被别的MySQL服务所使用。
并删除auto.cnf (有就删除没有就算了,因为复制master的uuid会一样)
修改端口,datadir(不要忘了)
2、启动slave服务器,登录
3、在slave端,配置master链接信息 (执行语句)
1) 配置
Mysql> change master to
master_host=‘192.168.77.1’, #master IP
master_user=‘yhptest’, #master数据库通过GRANT授权的账号
master_password=‘admin’, #master数据库通过GRANT授权的密码
master_port=3307, #master数据库的端口
master_log_file=‘mysql-bin.000001’,
#master数据库中通过show master status显示的File名称
master_log_pos=296
#master数据库的通过show master status显示的Position的值
2) (重新启动slave)连接
Mysql> start slave;
3)主从同步检查
show slave status;
其中Slave_IO_Running 与 Slave_SQL_Running 的值都必须为YES,才表明状态正常。( 如果不是yes 看slave 的 PC201806161502.err 错误报告)
4、 测试
1) 在master上,建库、建表、添加数据
2) 刷新slave库,记录也存在
由此,整个MySQL主从复制的过程就完成了,接下来,我们进行MySQL读写分离的安装与配置。
5.3.读写分离
使用MySQL Proxy实现读写分离
在此使用配置文件的方式来进行配置。
配置文件mysql-proxy.conf中的内容主要包括:(不要放在有空格的目录下)
[mysql-proxy]
admin-username=proxy
admin-password=proxy
admin-lua-script=C:/ProgramData/MySQL/mysql-proxy/lib/mysql-proxy/lua/admin.lua
proxy-backend-addresses=192.168.0.100:3307
proxy-read-only-backend-addresses=192.168.0.100:3308
proxy-lua-script=C:/ProgramData/MySQL/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua
log-file=C:/ProgramData/MySQL/mysql-proxy/mysql-proxy.log
log-level=debug
daemon=true
keepalive=true
执行命令:
mysql-proxy -P 192.168.0.100:4040 --defaults-file=“C:\ProgramData\MySQL\mysql-proxy\mysql-proxy.conf”
查看日志文件mysql-proxy.log:
2015-10-19 16:27:40: (critical) plugin proxy 0.8.5 started
2015-10-19 16:27:40: (debug) max open file-descriptors = 512
2015-10-19 16:27:40: (message) proxy listening on port 192.168.174.133:4040
2015-10-19 16:27:40: (message) added read/write backend: 192.168.174.130:3306
2015-10-19 16:27:40: (message) added read-only backend: 192.168.174.131:3306
出现以上日志信息则表示MySQL Proxy启动成功,此时便可以实现读写分离了。
注意:由于rw-splitting.lua中的min_idle_connections的默认值为4,即当会话数达到最小为4时,才会进行读写分离,在此我们将其改为1,则可直接进行读写分离。
后端主机需要创建授权帐号 (nvcat 登录必须是主机ip地址,不能是localhost,要不然账号登录不上)
mysql> GRANT ALL ON . TO mike@‘192.168.%.%’ IDENTIFIED BY ‘321’;
mysql> FLUSH PRIVILEGES;
Cmd 命令服务删除:
sc delete MySQL_salve