MySQL分区、主从复制,数据库优化

mysql8优化专题:

MySQL数据库单表最大可支持数据没有明确限制,业界流传500万,阿里手册提出单表行数超过500w或者单表容量数据超过2GB,才推荐进行分库分表。

1、慢查询开启

 -查看慢查询开启状态:show VARIABLES like 'slow_query%';
 -开启慢查询记录日志(重启失效):set global slow_query_log='ON';
 -设置慢查询sql执行记录时间(S):set global long_query_time=2;
 -永久生效配置:到mysql安装目录下打开my.ini(linux为my.cnf)配置文件添加:
 在my.ini配置文件添加如下配置应该在[mysqld]之下,否则会报错
 #开启慢查询
 slow_query_log=ON
 #最长执行时间 (查询的最长时间,超过了这个时间则记录到日志中)
 long_query_time=2
 添加完成后重启数据库:mysqld restart

2、数据库的优化策略

 1)优化sql和索引
 2)加缓存,memcache和redis等
 3)以上两点做了后还是慢,就做主从复制或主主复制,读写分离,可以在应用层做,效率高,也可以用第三方工具,推荐360的atlas,其他的要么效率不高,要么没人维护
 4)如果以上做了之后还是慢,那么先试试mysql自带的分区表,无需更改代码,但是sql语句是需要针对分区表做优化的,sql条件中要带上分区条件的列,从而使查询定位到少量的分区上,否则就会扫描全部分区
 5)如果以上都做了,那就先做垂直拆分,其实就是根据模块的耦合度,将一个大的服务分为若干小服务,从而根据小服务的业务拆分数据库字段
 6)最后才是水平拆分,针对数据量大的表,这一步最麻烦,也最能考验技术水平,要选择一个合理的sharding key,为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql中尽量带shardingkey,将数据定位到限定的表上去查,而不是扫描全部的表

3、索引相关优化以及注意问题

 1)应尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描
 2)值分布很稀少的字段不适合建立索引,例如“性别”这种只有两三个值的字段
 3)字符只创建前缀索引
 4)字符字段最好不要做主键
 5)不用外键,由程序保证约束
 6)尽量不用UNIQUE,由程序保证约束
 7)使用多列索引时,注意索引内字段顺序和查询条件中的字段顺序,同时删除不必要的单列索引
 8)不要使用子查询,子查询时MYSQL会去创建临时表,查询完毕后再删除这些临时表,所以这里会多一个创建和销毁临时表的过程
 9)LIKE关键字匹配’%’开头的字符串,不会使用索引.
 10)OR关键字的两个字段必须都是用了索引,该查询才会使用索引.
 11)使用多列索引必须满足最左匹配.

4、mysql文件类型

 -frm文件:表结构文件
 -ibd文件:innodDB中,索引和数据都在同一个文件.ibdata(你的执行结果可能是.MYD索引文件和.MYI数据文件,这是MyIsam存储引擎,对应着innodDB的ibd文件),因为order这张表分为5个区,所以有5个这样的文件
 -par文件:你执行的结果中可能有.par文件,也可能没有。从MySQL5.7.6开始,不再创建.par分区定义文件,分区定义存储在内部数据字典中。

5、mysql支持的分区方式

 -RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区。使用较多
 -LIST分区:类似于按照RANGE分区,区别在于LIST分区是基于列值匹配的一个离散值集合中的某个值来进行选择。使用一般
 -HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的的这些行的列值进行计算,这个函数可以包含MySQL中有效的、产生非负整数值的任何表达式。使用频率较多。
 -KEY分区:类似于按照HASH分区,区别在于KEY分区只支持计算一列或者多列,且MySQL服务器提供其自身的hash函数,必须有一列或多列包含整数值。使用频率一般

6、MySQL分库分表策略

 分为proxy模式和client模式

7、MySQL分区

-创建表的时候进行分区
CREATE TABLE tb_tr (
	id INT COMMENT "ID编号", 
	name VARCHAR(50) COMMENT "名称", 
	purchased DATE COMMENT "购买时间",
	PRIMARY KEY (`id`, `purchased`) USING BTREE COMMENT "主键",
	INDEX `idx_id`(id) COMMENT "索引-id",
	INDEX `idx_name`(name) COMMENT "索引-名称",
	INDEX `idx_purchased`(purchased) COMMENT "索引-购买"
 ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic 
COMMENT '购买日志'
PARTITION BY RANGE( YEAR(purchased) ) (
	PARTITION p0 VALUES LESS THAN (1990) ENGINE = InnoDB,
	PARTITION p1 VALUES LESS THAN (1995) ENGINE = InnoDB,
	PARTITION p2 VALUES LESS THAN (2000) ENGINE = InnoDB,
	PARTITION p3 VALUES LESS THAN (2005) ENGINE = InnoDB,
	PARTITION p4 VALUES LESS THAN (2010) ENGINE = InnoDB,
	PARTITION p5 VALUES LESS THAN (2015) ENGINE = InnoDB,
    PARTITION p6 VALUES LESS THAN (2020) ENGINE = InnoDB,
	PARTITION pmax VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB
);
-对已有表进行分区
ALTER TABLE tb_tr PARTITION BY RANGE (id)(
  PARTITION p5 VALUES less than (5),
  PARTITION p8 VALUES less than (8)
);
-查询已经创建的表分区
SELECT * FROM information_schema.`PARTITIONS` WHERE table_schema = '数据库名' AND table_name = "表名";
-删除分区
ALTER TABLE tb_tr DROP PARTITION p4,p5,p6,p7;
-添加分区
ALTER TABLE tb_tr ADD PARTITION (
  PARTITION p7 VALUES LESS THAN (2010),
  PARTITION p6 VALUES LESS THAN MAXVALUE
);
-将一个分区重新规划为两个分区
ALTER TABLE tb_tr REORGANIZE PARTITION pmax INTO (
PARTITION p7 VALUES LESS THAN (2025) ENGINE = INNODB,
PARTITION n1 VALUES LESS THAN (MAXVALUE) ENGINE = INNODB
);
-MySQL的hash分区
CREATE TABLE clients (
	id INT,
	fname VARCHAR(30),
	lname VARCHAR(30),
	signed DATE
)
PARTITION BY HASH( MONTH(signed) )
--hash分区分为两种,一种是hash,另一种是线性hash,如PARTITION BY LINEAR HASH( MONTH(signed) )
PARTITIONS 12;
-将分区表从12个分区变为8个分区
ALTER TABLE clients COALESCE PARTITION 4;
-分区后的一些增删改查
DELETE FROM employees PARTITION (p0, p1) WHERE fname LIKE 'j%';
UPDATE employees PARTITION (p2) SET store_id = 2 WHERE fname = 'Jill';
SELECT * FROM employees PARTITION (p2);
INSERT INTO employees PARTITION (p3) VALUES (20, 'Jan', 'Jones', 1, 3);

8、MySQL主从复制原理

MySQL的主从复制中主要有三个线程:master(binlog dump thread)、slave(I/O thread,SQL thread),Master一条线程和slave中的两条线程。

  1) Master主库在事务提交时,会把数据变更记录在二进制文件Binlog中
  2) 从库读取主库的二进制文件Binlog,写入到从库的中继日志Relay Log
  3) slave重做中继日志中的事件,将改变反映它自己的数据

9、主从复制具体操作

  1. 准备两台服务器,并且安装好MySQL,并确保他们对应的3306端口是开启的
  2. 主库配置:
    修改配置文件/etc/my.cnf(windows环境应该是my.ini)
#mysql服务id,保证整个集群环境中唯一,取值范围:1-(2^32-1),默认为1
[mysqld]
server-id=1
#是否只读,1代表只读,0代表读写
read-only=0
#忽略的数据,指不需要同步的数据库
#binlog-ignore-db=mysql
#指定同步的数据库
#binlog-do-db=db01

重启MySQL服务器

systemctl restart mysqld

登录MySQL,创建远程连接的账号,并授予主从复制权限

 #创建itcast用户,并设置密码,该用户可在任意主机连接该MySQL服务,%是全部ip
 CREATE USER 'itcast'@'%' IDENTIFIED WITH mysql_native_password BY 'Root@123456';
 #为'itcast'@'%'用户分配主从复制权限
 GRANT REPLICATION SLAVE ON *.* TO 'itcast'@'%';

通过指令,查看二进制日志坐标

show master status;
  1. 从库配置:
    修改配置文件/etc/my.cnf
#MySQL服务id,保证整个集群环境中唯一,和主库不一致即可
[mysqld]
server-id=2
#是否只读,1代表只读,0代表读写
read-only=1

重新启动MySQL服务

systemctl restart mysqld

登录MySQL,设置主库信息配置

#SOURCE_HOST:主库ip地址,对应MASTER_HOST
#SOURCE_USER:连接主库用户名,对应MASTER_USER
#SOURCE_PASSWORD:连接主库的密码,对应MASTER_PASSWORD
#SOURCE_LOG_FILE:binlog日志文件名,对应MASTER_LOG_FILE
#SOURCE_LOG_POS:binlog日志文件位置,对应MASTER_LOG_POS
#这个是8.0.23版本的语法
CHANGE REPLICATION SOURCE TO SOURCE_HOST='XXX.XXX',SOURCE_USER='XXX',SOURCE_PASSWORD='XXX',SOURCE_LOG_FILE='XXX',SOURCE_LOG_POS=XXX;
#8.0.23版本之前的语法如下
CHANGE MASTER TO MASTER_HOST='XXX',MASTER_USER='XXX',MASTER_PASSWORD='XXX',MASTER_LOG_FILE='XXX',MASTER_LOG_POS=XXX;

开启同步操作

start replica;#8.0.22之后
start slave;  #8.0.22之前

查看主从同步状态

show replica status;  #8.0.22之后
show slave status;    #8.0.22之前
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值