mysql学习记录

文章目录

  • mysql的架构介绍
    • Mysql简介
      • 概述
      • 高级MYSQL
    • MysqlLinux版的安装
    • Mysql的配置文件
      • 二进制日志log-bin
      • 错误日志log-error
      • 查询日志log
      • 数据文件
    • Mysql逻辑架构介绍
    • Mysql存储引擎
  • 索引优化分析
    • 性能下降SQL慢、执行时间长、等待时间长
    • 常见通用的Join查询
      • SQL执行顺序
      • Join图
    • 索引简介
      • 索引分类
        • 单值索引
        • 唯一索引
        • 复合索引
        • 基本语法
        • 哪些情况建立索引?
        • 哪些情况不要建立索引?
    • 性能分析
      • Mysql Query Optimizer
      • MYSQL常见瓶颈
        • CPU
        • IO
        • 服务器硬件的性能瓶颈
      • Explain
    • 索引优化
      • 索引分析
        • 单表
        • 两表
        • 三表
      • 索引失效
      • 一般性建议
  • 查询截取分析
    • 查询优化
      • 永远小表驱动大表
      • order by关键字优化
      • group by 关键字优化
    • 慢查询日志
    • 批量数据脚本
    • show Profile
    • 全局查询日志
  • Mysql锁机制
    • 概述
      • 定义
      • 生活购物
      • 锁的分类
        • 从对数据库操作的类型(读\写)分
        • 从对数据操作的力度分
    • 三锁
      • 表锁(偏读)
      • 行锁(偏写)
      • 页锁
  • 主从复制
    • 复制的基本原理
    • 复制的基本原则
    • 复制的最大问题
    • 一主一从常见配置

mysql的架构介绍

Mysql简介

概述

MYSQL是一个关系型数据库管理系统,由瑞典MYSQL AB公司开发,目前属于Oracle公司

高级MYSQL

mysql内核

sql优化工程师

mysql服务器的优化

各种参数常量设定

查询语句优化

主从复制

软硬件升级

容灾备份

sql编程

MysqlLinux版的安装

wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm

yum -y install mysql57-community-release-el7-10.noarch.rpm

yum -y install mysql-community-server

启动mysql:

systemctl start mysqld.service

查看是否启动成功:

systemctl status mysqld.service

查看生成的密码:

grep "password" /var/log/mysqld.log

用刚刚的密码登录mysql:

mysql -u root -p密码

关闭密码长度限制:

set global validate_password_policy=0;

set global validate_password_length=1;

修改密码:

ALTER USER 'root'@'localhost' IDENTIFIED BY '自己想设置的密码'; 

顺便打开远程访问:GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '密码' WITH GRANT OPTION;

修改字符集(my.cnf):character-set-server=utf8

路径 解释 备注
/var/lib/mysql mysql数据库文件存放位置 mysql数据文件(数据库、表)存放位置
/etc/my.cnf mysql配置文件
/usr/bin 相关命令目录

Mysql的配置文件

二进制日志log-bin

主要用于主从复制  log-bin=路径

错误日志log-error

默认是关闭的,记录严重的警告和错误信息,每次启动和关闭的详细信息等  log-error=路径

查询日志log

默认关闭,记录查询的sql语句,如果开启会减低mysql的整体性能。

数据文件

frm:存放表结构
myd:myisam 数据
myi:myisam 索引
idb:innodb 数据和索引

Mysql逻辑架构介绍

1. 连接层
2. 服务层
3. 引擎层
4. 存储层

Mysql存储引擎

查看已提供的引擎:show engines;

查看默认存储引擎:show variables like '%storage_engine%';'

对比项 MYISAM InnoDB
主外键 不支持 支持
事务 不支持 支持
行表锁 表锁,即使操作一条记录也会锁住整个表,不适合高并发的操作 行锁,操作时只锁定某一行,不对其他行有影响,适合高并发
缓存 只缓存索引,不缓存真实数据 不仅缓存索引还要缓存真实数据,对内存要求较高,而且内存大小对性能有决定性的影响
表空间
关注点 性能 事务
默认安装 Y Y

索引优化分析

性能下降SQL慢、执行时间长、等待时间长

1. 查询语句写的烂

2. 索引失效
	单值 idx_user_name
	复合 idx_user_nameEmail

3. 关联查询太多join(设计缺陷或不得已的需求)

4. 服务器调优及各个参数设置(缓冲、线程数等)

常见通用的Join查询

SQL执行顺序

手写

按照自己想法

机读顺序

from 笛卡尔积
on 主表保留
join 不符合ON也添加
Where 非聚合 非select别名
group by 改变对表的引用
having 只作用分组后
select distinct
order by 可使用select别名
limit rows offset

Join图

sql-join

索引简介

索引:排好序的快速查找数据结构

一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上。

B+Tree实现

索引分类

单值索引

即一个索引只包含单个列,一个表可以有多个单列索引

唯一索引

索引列的值必须唯一,但允许有空值

复合索引

一个索引包含多个列

基本语法

CREATE [UNIQUE] INDEX indexName ON mytable(columnname(length));
ALTER mytable ADD [UNIQUE] INDEX indexName ON (columnname(length));

DROP INDEX indexName ON mytable;

SHOW INDEX FROM table_name\G;

哪些情况建立索引?

  1. 主键自动建立唯一索引
  2. 频繁作为查询条件的字段应该创建索引
  3. 查询中与其他表关联的字段,外键关系建立索引
  4. 频繁更新的字段不适合创建索引-不但要更新数据还要更新索引
  5. where条件用不到的字段不创建索引
  6. 单键/组合索引的选择问题(在高并发下倾向创建组合索引)
  7. 查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
  8. 查询中统计或者分组的字段

哪些情况不要建立索引?

  1. 表记录太少
  2. 经常增删改的表
  3. 数据重复且分布平均的表

性能分析

Mysql Query Optimizer

提供mysql认为最优的执行计划(不一定是DBA认为最优的)

MYSQL常见瓶颈

CPU

CPU在饱和的时候一般发生在数据装入内存或从磁盘上读取数据的时候

IO

磁盘I/O瓶颈发生在装入数据远大于内存容量的时候

服务器硬件的性能瓶颈

top,free,iostat和vmstat来查看系统的性能

Explain

查看执行计划

作用

表的读取顺序
数据读取操作的操作类型
哪些索引可以使用
哪些索引被实际使用
表之间的引用
每张表有多少行被优化器查询

字段解释

id:	id相同,执行顺序由上到下
	id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先执行
	
select_type: PRIMARY 查询中若包含任何复杂的子查询,最外层查询被标记为PRIMARY
			 SUBQUERY 在select或者where列表中包含了子查询
			 SIMPLE 简单的select查询,查询中不包含子查询或者UNION
			 DERIVED 在from列表中包含的子查询被标记为DERIVED(衍生)mysql会递归执行这些子查询,把结果放在临时表里
			 UNION 若第二个select出现在UNION之后,则被标记为UNION;若UNION包含在from子句的子查询中,外层select将被标记为DERIVED
			 UNION RESULT 从UNION表获取结果的select
			 
type:system>const>eq_ref>ref>range>index>All
	 system 表中只有一行记录(等于系统表),这是const类型的特例,平时不会出现
	 const 表示通过索引一次就找到了,const用于比较primary或者unique索引。因为只匹配一行数据,如将主键置于where列表中,mysql就能将该查询转换为一个常量
	 eq_ref 唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描
	 ref 非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,他可能找到多个复合条件的行,索引他应该属于查找和扫描的混合体
	 range 只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引一般就是在你的where语句中出现between、<、>、in等的查询 这种范围扫描索引扫描比全表扫描要好,因为它只需要开始于索引的某一点,结束于索引的某一点,不用扫描全部索引
	 index Full Index Scan,index与All区别为index类型只遍历索引树。这通常比All快,因为索引文件通常比数据文件小。(也就是说虽然all和index都是读全表,但index是从索引中读取的,而all是从磁盘中读的)
	
possible_keys:显示可能应用在这张表中的索引,一个或者多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用

key:实际使用的索引。如果为null,则没有使用索引 查询中若使用了覆盖索引,则该索引出现在key列表中

key_len:表示索引中使用的字节数,可通过该列计算查询中使用的索引长度。在不损失精确性的情况下,长度越短越好 key_len显示的值为索引字段的最大可能长度,并非实际长度,即key_len是根据表定义计算而得,不是通过表内检索出的

ref:显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或者常量被用于查找索引列上的值

rows: 根据表统计信息及索引选用情况,大致估算出找到所需记录所需的读取行数

extra:  1. Using filesort 说明mysql会对数据使用一个外部的索引顺序,而不是按照表内的索引顺序进行读取 mysql无法使用索引完成的排序操作称为“文件排序”
		2. Using temporary 使用了临时表保存中间结果,mysql在对查询结果排序时使用了临时表。常见于排序order by或者分组查询group by
		3. Using index 表示相应的select操作中使用了覆盖索引(Covering Index),避免访问表的数据行 如果同时出现using where,表示索引被用来执行索引键值的查找 如果没有同时出现using where,表明索引用来读取数据而非执行查找动作
		4. using where 表明使用了where过滤
		5. using join buffer 使用了连接缓存
		6. impossible where where子句的值总是false,不能用来获取任何元组
		7. select tables optimized away 在没有groupby子句的情况下,基于索引优化MIN/MAX操作或者对于Myisam存储引擎优化count(*)操作,不必等到执行阶段再进行计算,查询执行计划生产的阶段即完成
		8. distinct 优化distinct操作,在找到第一个匹配的元组后即停止找同样值的动作

索引优化

索引分析

单表

范围后面索引失效,建索引的时候没有用范围字段

两表

小表驱动大表

三表

join的时候,与两表情况类似

索引失效

  1. 全值匹配我最爱

  2. 最佳左前缀法则

  3. 不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效转向全表扫描

  4. 存储引擎不能使用索引中范围条件右边的列

  5. 尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select *

  6. mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描

  7. is null,is not null也无法使用索引

  8. like以通配符开头(’%abc’)mysql索引失效会变成全表扫描的操作

    解决like’%字符串%'时索引不被使用的方法:覆盖索引

  9. 字符串不加单引号索引失效

  10. 少用or,用它来连接时会索引失效

定值、范围还是排序,一般order by是给个范围 group by基本上都需要进行排序,会有临时表产生,order by 定值不影响,倒序filesort

一般性建议

对于单值索引,尽量选择针对当前query过滤性更好的索引

在选择组合索引的时候,当前query中过滤性最好的字段在索引字段排序中,位置越靠前越好。

在选择组合索引的时候,尽量选择可以能够包含当前query中的where子句中更多字段的索引

尽可能提供分析统计信息和调整query的写法来表达选择合适索引的目的

全值匹配我最爱,最左前缀要遵循;

带头大哥不能死,中间兄弟不能断;

索引列上少计算,范围之后全失效;

Like百分写最右,覆盖索引不写星;

查询截取分析

查询优化

永远小表驱动大表

exists:将主查询的数据,放到子查询中做条件验证,根据验证结果(true或false)来决定主查询的结果是否保留。

order by关键字优化

order by子句,尽量使用index方式排序,避免使用filesort方式排序

尽可能在索引列上完成排序操作,遵照索引建的最佳左前缀

mysql支持二种方式排序,filesort和index,index效率高,它指mysql扫描索引本身完成排序。filesort方式效率低。

order by满足两种情况,会使用index方式排序:

  1. order by语句使用索引最左前列
  2. 使用where子句与order by子句条件列组合满足索引最左前列

如果不在索引列上,filesort有两种算法:双路排序和单路排序

双路排序(mysql4.1之前):两次扫描磁盘,最终得到数据,读取行指针和orderby列,对他们进行排序。从磁盘取排序字段,在buffer进行排序,再去磁盘取其他字段。

单路排序:从磁盘读取查询需要的索有列,按照orderby列在buffer对他们进行排序,然后扫描排序后的列表进行输出,他的效率更快一些,避免了二次读取数据。

单路问题:sort_buffer容量过小,会多次操作,产生大量io。修改max_length_for_sort_data

提高orderby查询速度:

  1. 不使用select *
  2. 尝试提高sort_buffer_size
  3. 尝试提高max_length_for_sort_data

key a_b_c(a,b,c)

orderby能使用最左前缀

  • order by a
  • order by a,b
  • order by a,b,c
  • order by a desc,b desc,c desc

如果where使用索引的最左前缀定义为常量,则order by能使用索引

  • where a=const order by b,c
  • where a=const and b=const order by c
  • where a=const and b>const order by b,c

不能使用索引进行排序

  • order by a asc ,b desc ,c desc //排序顺序不一致
  • where g = const order by b,c //a索引丢失
  • where a = const order by c //b索引丢失
  • where a = const order by a,d //d不是索引的一部分
  • where a in(…) order by b,c //对于排序来说,多个相等条件也是范围查询

group by 关键字优化

group by实质是先排序后进行分组,遵照索引的最佳左前缀

增大max_length_for_sort_data参数和sort_buffer_size参数

能用where 不要写having限定

其他和order by一致

慢查询日志

超过阙值(long_query_time)值的sql
mysql默认没有开启慢查询日志,如果不是调优需要,一般不建议启动该参数

默认:

SHOW VARIABLES LIKE '%slow_query_log%';

开启:

SET GLOBAL slow_query_log=1;
只对当前数据库生效

长期开启:
my.cnf
slow_query_log=1;
slow_query_log_file=/var/lib/mysql/slow_query_log.log

默认时间

SHOW VARIABLES LIKE '%long_query_time%';  //10秒

设置慢的阙值时间

set global long_query_time=3;//重新开启会话后生效

查看慢查询语句条数:

SHOW GLOBAL STATUS LIKE '%Slow_queries%';

my.cnf配置:

slow_query_log=1;
slow_query_log_file=/var/lib/mysql/slow_query_log.log
long_query_time=3;
log_output=FILE

日志分析工具mysqldumpslow

s:表示按照何种方式排序
c:访问次数
l:锁定时间
r:返回记录
t:查询时间
al:平均锁定时间
ar:平均返回记录数
at:平均查询时间
t:即为返回前面多少条的数据
g:后面搭配一个正则匹配模式,大小写不敏感

返回记录集最多的10个SQL
mysqldumpslow -s r -t 10 /var/lib/mysql/slow_query_log.log

返回访问次数最多的10个SQL
mysqldumpslow -s c -t 10 /var/lib/mysql/slow_query_log.log

按照时间排序的前10条里面含有左连接的查询语句
mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/slow_query_log.log

批量数据脚本

设置参数

 set global log_bin_trust_function_creators=1;

查看设置

 show variables like '%log_bin_trust_function_creators%';

创建表:

CREATE TABLE dept
(
id INT UNSIGNED PRIMARY KEY  AUTO_INCREMENT,
deptno INT unsigned NOT NULL DEFAULT 0,
dname VARCHAR(20) not null default "",
loc VARCHAR (13) not null default ""
)

CREATE TABLE emp
(
id int unsigned primary key auto_increment,
empno mediumint unsigned not null default 0,
ename varchar(20) not null default "",
job varchar(9) not null default "",
mgr mediumint unsigned not null default 0,
hiredate date not null,
sal decimal(7,2) not null,
comm decimal(7,2) not null,
deptno mediumint unsigned not null default 0
)ENGINE=INNODB DEFAULT CHARSET=utf8;
delimiter $$
create function ran_string(n int) returns varchar(255)
begin
declare chars_str varchar(100) default 'abcdefghijklmnopqrstuvwxyzQWERTYUIOPASDFGHJKLZXCVBNM';
declare return_str varchar(255) default '';
declare i int default 0;
while i < n do
set return_str = concat(return_str,substring(chars_str,floor(1+rand()*52),1));
set i=i+1;
end while;
return return_str;
end $$

delimiter $$
create function rand_num() returns int(5)
begin
declare i int default 0;
set i=floor(100+rand()*10);
return i;
end $$

delimiter $$
create procedure insert_emp(in start int(10),in max_num int(10))
begin
declare i int default 0;
set autocommit = 0;
repeat
set i = i+1;
insert into emp(empno,ename,job,mgr,hiredate,sal,comm,deptno) values((start+i),ran_string(6),'salesman',0001,curdate(),2000,400,rand_num());
until i=max_num
end repeat;
commit;
end $$

delimiter $$
create procedure insert_dept(in start int(10),in max_num int(10))
begin
declare i int default 0;
set autocommit = 0;
repeat
set i = i+1;
insert into dept(deptno,dname,loc) values((start+i),ran_string(10),ran_string(8));
until i=max_num
end repeat;
commit;
end $$
delimiter ;
call insert_dept(100,10);
delimiter ;
call insert_emp(100001,500000);

show Profile

mysql提供的可以用来分析当前会话中语句执行的资源消耗情况。可以用来sql的调优的测量
默认情况下,参数处于关闭状态,并保存最近15次的运行结果

默认关闭的

SHOW VARIABLES LIKE 'profiling';

开启:

set profiling = on;

执行sql

select * from emp group by id limit 150000;

查看mysql历史执行语句:

SHOW PROFILES;

诊断sql

SHOW PROFILE CPU,BLOCK IO FOR QUERY 22;//22 是show profiles中的query id

常见问题:

converting HEAD to MyISAM查询结果太大,内存都不够用了往磁盘上搬。
Create tmp table 创建临时表 还要拷贝数据到临时表,用完删除临时表。
Copying to tmp table on disk 把内存中临时表复制到磁盘,危险
locked

全局查询日志

开启

set global general_log=1;
set global log_output='TABLE';

查看结果:

select * from mysql.general_log;

Mysql锁机制

概述

定义

锁是计算机协调多个进程或线程并发访问某一资源的机制

生活购物

购物的时候,库存只有一件怎么解决?

锁的分类

从对数据库操作的类型(读\写)分

读锁(共享锁):针对同一份数据,多个读操作可以同时进行二不会互相影响。

写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁。

从对数据操作的力度分

表锁

行锁

三锁

表锁(偏读)

偏向MyISAM存储引擎,开销小,加锁快;无死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

建表

CREATE TABLE mylock (
id INT not NULL PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
)ENGINE MYISAM;

INSERT INTO mylock(NAME) VALUE('a');
INSERT INTO mylock(NAME) VALUE('b');
INSERT INTO mylock(NAME) VALUE('c');
INSERT INTO mylock(NAME) VALUE('d');
INSERT INTO mylock(NAME) VALUE('e');

手动添加表锁

lock table 表名 read(write),表名2 read(write),其他;

查看表上加过的锁

show open tables;

释放表锁

unlock tables;
添加读锁之后,
当前session可以查询表记录,其他session也可以查询该表记录
当前session不能查询其他没有锁定的表,其他session可以查询或者更新未锁定的表
当前session插入或者更新锁定的表都会提示错误,其他session插入或者更新会一直等待
当前session释放锁,其他session等待执行操作。
添加写锁之后,
当前session对锁定的表查询、更新、插入都可以执行,其他session对锁定表的操作阻塞
当前session释放锁之后,其他session继续操作
MyISAM在执行查询语句(select)前,会自动给涉及的所有表添加读锁,在执行增删改操作前,会自动给涉及的表添加写锁。
简而言之,就是读锁会阻塞写,但是不会阻塞读。而写锁会把读和写都阻塞。
show status like 'table%';
 Table_locks_immediate:产生表级锁定的次数,表示可以立即获取锁的查询次数,每立即获取锁值加1;
 Table_locks_waited: 出现表级锁定争用而发生等待的次数(不能立即获取锁的次数,每等待一次加1),此值高说明存在着严重的表级锁争用情况
MyISAM的读写锁调度是写优先,这也是myisam不适合做写为主表的引擎。因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永远阻塞

行锁(偏写)

偏向InnoDB存储引擎,开销大,加锁慢;会出现死锁;锁定力度最小,发生锁冲突的概率最低,并发度也最高。

查看mysql默认隔离级别

show variables like 'tx_isolation';

建表

create table test_innodb_lock( a int(11), b varchar(16) )engine=innodb;

insert into test_innodb_lock values(1, 'b2');
insert into test_innodb_lock values(3, '3');
insert into test_innodb_lock values(4, '4000');
insert into test_innodb_lock values(5, '5000');
insert into test_innodb_lock values(6, '6000');
insert into test_innodb_lock values(7, '7000');
insert into test_innodb_lock values(8, '8000');
insert into test_innodb_lock values(9, '9000');
insert into test_innodb_lock values(1, 'b1000');

create index test_innodb_a_ind on test_innodb_lock(a);
create index test_innodb_b_ind on test_innodb_lock(b);

案例

set autocommit=0;(两个session都)
当前session修改数据,然后select查看修改结果,其他session看到的是未修改的数据,读己之所写。
两个session操作相同的行,后面的阻塞,前面的提交后再执行。
当前窗口commit后,其他关闭autocommit的窗口要commit之后才能看见结果。
修改数据的时候索引失效(例如varchar不加单引号,导致索引失效),会导致行锁变表锁。

间隙锁

当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,Innodb会给符合条件的已有数据记录的索引项添加锁;对于键值在条件范围内但并不存在的记录,也叫“间隙(GAP)”,Innodb也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key锁)。
当前session(关闭自动提交)
update test_innodb_lock set b='0629' where a>1 and a<6;
其他session
insert into test_innodb_lock values(2,'2000');
其他session 出现阻塞的情况

如何锁定一行

当前session
begin;
select * from test_innodb_lock where a=8 for update;
其他session
update test_innodb_lock set b='8001' where a=8;
其他session会出现阻塞

分析行锁

show status like 'innodb_row_lock%';

Innodb_row_lock_current_waits :当前正在等待锁定的数量
Innodb_row_lock_time          :从系统启动到现在锁定总时间长度
Innodb_row_lock_time_avg      :每次等待所花平均时间
Innodb_row_lock_time_max      :从系统启动到现在等待最长的一次所花的时间
Innodb_row_lock_waits         :系统启动后到现在总共等待的次数
特别注意:
Innodb_row_lock_time          
Innodb_row_lock_time_avg
Innodb_row_lock_waits

优化建议

尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁
合理设计索引,尽量较小锁的范围
尽可能较少索引条件,避免间隙锁
尽量控制事务大小,减少锁定资源量和时间长度
尽可能低级别事务隔离

页锁

开销和加锁时间界于表锁和行锁之间,会出现死锁;锁定粒度界于行锁和表锁之间,并发度一般。

主从复制

复制的基本原理

slave会从master读取binlog来进行数据同步
1. master将改变记录到二进制日志(binary log)。这些记录过程叫做二进制日志事件,binary log events;
2. slave将master的binary log events拷贝到它的中继日志(relay log);
3. slave重做中继日志中的事件,将改变应用到自己的数据库中。mysql复制是异步的且串行化的

复制的基本原则

每个salve只有一个master
每个slave只能有一个唯一的服务器ID
每个master可以有多个slave

复制的最大问题

延时

一主一从常见配置

mysql版本一致且后台以服务运行

主从都配置在[mysqld]节点下,都是小写

修改主机my.cnf配置文件

# 唯一 必须
server-id=1 

# 启用二进制日志 必须
log-bin=/var/lib/mysql/data/mysqlbin 

# 启用错误日志 可选
log-err=/var/lib/mysql/data/mysqlerr

# 根路径 可选
basedir=/var/lib/mysql/

# 临时目录 可选
tmpdir=/var/lib/mysql/

# 数据目录 可选
datadir=/var/lib/mysql/

# 主机读写都可以
read-only=0

# 设置不要复制的数据库 可选
binlog-ignore-db=mysql

# 设置需要复制的数据库 可选
binlog-do-db=pzh

修改从机my.cnf配置文件

# 唯一 必须
server-id=1 

# 启用二进制日志 必须
log-bin=/var/lib/mysql/data/mysqlbin 

master

[mysqld]
datadir=/var/lib/mysql
basedir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=root
port=3306
symbolic-links=0

server-id=1          
binlog-ignore-db=mysql  
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=sys
log-bin=mysql-bin         
expire_logs_days=90 

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

slave

[mysqld]
basedir=/var/lib/mysql
datadir=/var/lib/mysql  
socket=/var/lib/mysql/mysql.sock
user=root
port=3306
server-id=2    
log-bin=mysql-bin                    
skip_slave_start=1        
read_only = 1              
master_info_repository=TABLE
relay_log_info_repository=TABLE
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

首先关闭防火墙
master:

grant replication slave on *.* to 'root'@'192.168.101.129' identified by 'root';

flush privileges;

show master status\G

 slave:

grant replication slave on *.* to 'root'@'192.168.101.128' identified by 'root';

flush privileges;

change master to master_host='192.168.101.128', master_user='root', master_password='root',master_log_file='mysql-bin.000006', master_log_pos=306;
start slave;

show slave status\G

你可能感兴趣的:(Mysql)