高性能MySQL总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高性能MySQL总结相关的知识,希望对你有一定的参考价值。
目录
- MySQL主从复制
- 复制过滤器
- 复制与监控
- 主从复制的读写分离
- 备份与恢复
- 表分区
一、mysql主从复制
复制拓扑:
主机 | IP | 备注 |
---|---|---|
Mysql-master.linux.com | 192.168.239.142 | master |
Mysql-slave.linux.com | 192.168.239.143 | slave |
1、创建复制账号
连接主数据库服务器,创建具有replication slave和replication client权限的账号。
[[email protected] ~]# mysql
mysql> grant replication slave,replication client on *.* to [email protected]‘192.168.239.%‘ identified by ‘centos‘;
2、配置主从节点
主节点:
[[email protected] ~]# vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# 新增加如下两行
log_bin=/data/mysql/logs/mysql-bin
server_id=10
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
log_bin指定生成的二进制日子文件的目录和文件名
server_id指定唯一标识的数据库ID
从节点:
[[email protected] ~]# vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# 新增如下
server_id=20
relay_log=/data/mysql/logs/mysql-relay-bin
read_only=1
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
relay_log指定中继日志的目录和文件名
最后重启主从数据库服务。
3、从节点连接主节点
[[email protected] ~]# mysql
mysql> change master to master_host=‘192.168.239.142‘,master_user=‘replicater‘,master_password=‘centos‘,master_log_file=‘mysql-bin.000003‘,master_log_pos=283;
其中master_log_file和master_log_pos可以根据主节点的show master status语句查询到。
[[email protected] ~]# mysql
mysql> show slave statusG;
可以看到从节点的IO线程和SQL线程并没有启动。那是因为还没有启动从节点的复制。
接下启动从节点的复制,可以看到从节点的IO线程和SQL线程启动。
mysql> start slave;
到此为止MySQL主从复制已经配置完成,以后只要主机节点的数据发生变化,从节点也会跟着变化。例如:
接着从节点也会相应的生成mydb数据库。
另外也可以看到读取二进制文件的位置也发生了变化。(从283增长为336)
二、复制过滤器
1、主库过滤
在主库上进行过滤只能针对数据库进行限制,而无法针对表进行过滤。
binlog_do_db=指定更新数据写入二进制日志文件的数据库,白名单
binlog_ignore_db=指定更新数据不写入二进制文件的数据库,黑名单
2、从库过滤
从库的SQL线程只对关心的数据库,表进行重放,以此来实现从库的过滤,可以发现,从库过滤不仅可是针对数据库,也可以针对表。
Replicate_Do_DB=
Replicate_Ignore_DB=
Replicate_Do_Table=
Replicate_Igonre_Table=
Replicate_Wild_Do_Table=
Replicate_Wild_Ignore_Table=
三、复制的监控与维护
随着时间的推移,数据库中的日志文件会日积月累,并且会占用大量的磁盘空间。因此就需要对一些日志文件进行管理。
1、清理日志
对于数据库的二进制日志文件,不能简单地使用rm命令进行删除,如果直接删除的话,用于记录二进制日志文件的index文件没有修改,这会造成数据库复制时候的错误。因此需要使用专门的工具清理日志。
命令PURGE:
格式:PURGE MASTER|BINARY LOGS TO ‘log_name‘
2、复制监控
主库:
?SHOW MASTER STATUS;
?SHOW BINLOG EVENTS;
?SHOW BINARY LOGS;
从库:
?SHOW SLAVE STATUSG;
其中的Seconds_Behind_Master参数表示从库落后于主库多长时间。解决主从数据不一致的问题可以尝试重新启动SQL线程。
四、主从复制的读写分离
借助SQL router(read/write spliter)实现。
目前实现MySQL集群读写分离的中间件很多,这里用ProxySQL来实现读写分离。
环境拓扑:
IP地址 | 角色 |
---|---|
192.168.239.129 | ProxySQL主机 |
192.168.239.142 | mysql主节点 |
192.168.239.143 | mysql从节点 |
具体操作:
1、mysql主从节点实现主从复制
这一步骤引用一、MySQL主从复制
的例子
2、安装ProxySQL中间件
ProxySQL的下载地址为https://github.com/sysown/proxysql/releases
上边有对应的操作系统的版本,下载即可
[[email protected] src]# pwd
/usr/local/src
[[email protected] src]# ls proxysql-1.4.10-1-centos67.x86_64.rpm
proxysql-1.4.10-1-centos67.x86_64.rpm
[[email protected] src]# yum -y install proxysql-1.4.10-1-centos67.x86_64.rpm
ProxySQL提供了如下的文件。其中的/etc/proxysql.cnf文件是proxysql服务启动时候的初始化配置。
下边的操作可以直接全部在/etc/proxysql.cnf中直接配置,启动proxysql服务就可以一步到位;当然还可以通过管理端(下边有提到)连接ProxySQL,通过SQL语句一步一步的完成配置。
这里通过/etc/proxysql.cnf完成。
3、创建ProxySQL管理账号
ProxySQL会启动两种类型的端口,一类管理端口,用于管理配置ProxySQL,仅限本地登录;一类客户端口,用于连接后端的mysql。他们默认分别监听在6032和6033端口。
首先配置ProxySQL的管理端,创建管理账号。
添加如下内容:
其中
参数 | 作用 |
---|---|
admin_credentials | 指定连接管理端的用户和密码 |
mysql_ifaces | 指定连接管理端的IP和端口 |
4、配置后端的mysql
相关的配置内容如下:
mysql_servers =
(
{
address = "192.168.239.142" # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
port = 3306 # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
hostgroup = 1 # no default, required
status = "ONLINE" # default: ONLINE
weight = 1 # default: 1
compression = 0 # default: 0
max_replication_lag = 10 # default 0 . If greater than 0 and replication lag passes such threshold, the server is shunned
},
{
address = "192.168.239.143"
port = 3306
hostgroup = 2
status = "ONLINE"
weight = 1
compression = 0
max_replication_lag = 10
}
)
address?指定后端mysql的IP地址
port?指定后端mysql的port
hostgroup?指定该mysql的组id,这里规划的是1组进行写操作,2组进行读操作
5、创建连接mysql的账户
这一步操作需要在后端的两台mysql主机分别进行。分别创建连接账户proxysql,并赋予该账户全部权限。并且该账户也可以通过登录ProxySQL主机然后连接后端mysql。
主节点:
[[email protected] ~]# mysql
([email protected]) [none]> grant all on *.* to [email protected]‘192.168.239.%‘ identified by ‘proxysql‘;
从节点:
[[email protected] ~]# mysql
([email protected]) [none]> grant all on *.* to [email protected]‘192.168.239.%‘ identified by ‘proxysql‘;
然后将连接mysql的账户proxysql添加到ProxySQL主机,ProxySQL主机就是通过这个账号连接后端mysql并进行操作。在/etc/proxysql.cnf添加如下内容,
mysql_users:
(
{
username = "proxysql" # no default , required
password = "proxysql" # default: ‘‘
default_hostgroup = 1 # default: 0
active = 1 # default: 1
}
)
default_hostgroup=1表示ProxySQL主机默认将SQL事件调度到1组,一般为进行写操作的那个组。
6、添加规则到ProxySQL主机
在/etc/proxysql.cnf中添加如下内容:
mysql_query_rules:
(
{
rule_id=1
active=1
match_pattern="^SELECT .* FOR UPDATE$"
destination_hostgroup=1
apply=1
},
{
rule_id=2
active=1
match_pattern="^SELECT"
destination_hostgroup=2
apply=1
}
)
select开头的查询语句调度到2组(即读操作的组),但是特别注意select ... for update之类的语句,也是会修改数据,因此需要将其调度到1组(即写操作的组),剩下的SQL语句全部调度到default_hostgroup定义的默认组。
关于是否定义监控用户,简单起见,这里没有在后端mysql中创建,监控用户可以用来监控后端mysql节点的状态信息,并且可以根据后端mysql的read_only参数自动地将其定义为只读组。还有因为这里将读组和写组已经定义在mysql_servers =中,因此也无需创建监控用户。
/etc/proxysql.cnf的其他内容保持默认。然后启动proxysql服务。
7、测试读写分离
通过proxysql账户连接ProxySQL主机,分别进行相关的查询操作和更改数据的操作,
[[email protected] ~]# mysql -uproxysql -h127.0.0.1 -P6033 -pproxysql
([email protected]) [(none)]> select user,host from mysql.user;
([email protected]) [(none)]> create database mydb2;
然后通过管理账户登录ProxySQL查看具体的连接状态
[[email protected] ~]# mysql -uadmin -h127.0.0.1 -P6032 -padmin
([email protected]) [(none)]> select * from stats_mysql_query_digest;
可以看到读操作调度到了2组,写操作调度了1组。读写分离成功。
五、备份与恢复
5.1 逻辑备份工具mysqldump
mysqldump是mysql自带的用于逻辑备份的工具。
下面是mysqldump工具常用方式的几个实例:
1. 备份所有数据库到单个文件
# 将192.168.239.143主机的mysql上所有库备份到本地root/backup目录的dump.sql文件
mysqldump --user=root --host=192.168.239.143 --password=centos --all-databases > /root/backup/dump.sql
2. 备份单个数据库到单个文件
# 将192.168.239.143主机的mysql上的mydb库备份到本地的dump.sql文件
mysqldump --user=root --host=192.168.239.143 --password=centos --databases mydb > /root/backup/dump.sql
3. 备份单个数据表到单个文件
# 将192.168.239.143主机上的mysql的mydb中的mytbl表备份到本地dump.sql文件
mysqldump --user=root --host=192.168.239.143 --password=centos --databases mydb --tables mytbl > /root/backup/dump.sql
# 将备份的单个文件恢复到mydb库中
mysql -u root mydb < /root/backup/dump.sql
如果恢复mysqldump备份的表出现了错误:ERROR 1046 (3D000) at line 22: No database selected,这是因为命令行中没有指定将表恢复到哪个数据库中。
4. mysqldump全量备份+mysqlbinlog增量备份
首先需要开启mysql服务的二进制日志功能,在/etc/my.cnf中添加log_bin=/data/mysql/logs/mysql-bin
[[email protected] ~]# mkdir -p /data/mysql/logs
[[email protected] ~]# chown mysql.mysql /data/mysql/logs
在某一时候对所有数据库做全量备份,
[[email protected] ~]# mysqldump --single-transaction --flush-logs --master-data=2 --user=root --host=127.0.0.1 > /root/backup/dump.`date +%F`.sql
[[email protected] ~]# cd /root/backup/
[[email protected] backup]# ls
dump.2018-08-31.sql
查看全量备份的数据信息,
现在再次增加新的数据,
([email protected]) [(none)]> insert into mydb.mytbl value (6,‘huangzhong‘,90),(7,‘zhugeliang‘,20);
因为误操作导致删除了所有数据库,
[[email protected] ~]# rm -rf /var/lib/mysql/*
到这里,如果仅仅依靠全量备份进行恢复,则mysql只能回到备份时刻点的数据,之后新增的数据并无法恢复,因此还需要借助二进制文件生成增量备份。
现在开始做增量备份,需要使用最新生成的二进制文件。
[[email protected] ~]# mysqlbinlog /data/mysql/logs/mysql-bin.000001 > /root/backup/mysql-bin.000001.sql
这样在/root/backup/目录下存在两个sql文件,一个全量备份,一个增量备份。
现在开始恢复删库之前的所有数据。
重启mysqld服务,
[[email protected] backup]# /etc/init.d/mysqld restart
[[email protected] backup]# mysql < /data/backup/dump.2018-08-31.sql
# 恢复全量备份之后,数据库中还没有后来新增的那两条数据
[[email protected] backup]# mysql < /data/backup/mysql-bin.000001.sql
# 恢复增量备份,恢复新增的数据
5.2 物理备份工具Xtrabackup
Xtrabackup的下载地址:https://www.percona.com/downloads/XtraBackup/LATEST/
1. xtrabackup全量备份与恢复
利用Xtrabackup工具中的innobackupex命令进行数据库的全量备份,完成之后会在指定目录下生成一个备份目录
[[email protected] ~]# innobackupex --user=root /root/backup/
[[email protected] ~]# cd /root/backup/
[[email protected] backup]# ls
2018-08-31_02-17-02
可以发现备份目录和原来数据库中的数据相似。
进行准备阶段,到了第二个阶段后,可以不用连接mysql。因此暂停mysql服务。
准备阶段的格式:innobackupes --appply-log <生成的全备份目录>
[[email protected] 2018-08-31_02-17-02]# /etc/init.d/mysqld stop
[[email protected] 2018-08-31_02-17-02]# innobackupex --apply-log /root/backup/2018-08-31_02-17-02/
因为误操作删除了所有数据库,
[[email protected] 2018-08-31_02-17-02]# rm -rf /var/lib/mysql/*
进行恢复,
[[email protected] 2018-08-31_02-17-02]# innobackupex --copy-back /root/backup/2018-08-31_02-17-02/
总之xtrabackup工具进行恢复数据操作经历三个阶段:备份、准备、恢复。当看到completed OK!字样就表示每个阶段执行成功。
完成之后在数据目录下生成的文件和目录的所属人和所属组都是root,需要将他们改为mysql
[[email protected] mysql]# chown -R mysql.mysql /var/lib/mysql/*
然后启动mysql,可以看到数据又回来了。
([email protected]) [(none)]> select * from mydb.mytbl;
2. xtrabackup增量备份与恢复
以上例的全量备份为基准,以此来做增量备份,
[[email protected] ~]# mkdir /root/backup/incremental
[[email protected] ~]# innobackupex --user=root --incremental /root/backup/incremental --incremental-basedir=/root/backup/2018-08-31_02-17-02/
再次在数据库中插入新的数据,
再做一次增量备份,这次以上一次的增量备份为基准,
[[email protected] incremental]# innobackupex --user=root --incremental /root/backup/incremental --incremental-basedir=/root/backup/incremental/2018-08-31_03-02-49/
这样就生成了两个增量备份文件。
因为误操作删除了所有数据库
[[email protected] ~]# rm -rf /var/lib/mysql/*
现在开始进行恢复操作。首先暂停mysql服务
1、对全量备份进行准备
[[email protected] ~]# innobackupex --apply-log --redo-only /root/backup/2018-08-31_02-17-02
2、合并增量备份,将两个增量备份添加到全量备份中
# 增量1增加到全量备份
[[email protected] ~]# innobackupex --apply-log --redo-only /root/backup/2018-08-31_02-17-02 --incremental-dir=/root/backup/incremental/2018-08-31_03-02-49
# 增量2增加到全量备份
[[email protected] ~]# innobackupex --apply-log /root/backup/2018-08-31_02-17-02/ --incremental-dir=/root/backup/incremental/2018-08-31_03-10-59/
3、对添加了增量备份的全量备份进行准备
[[email protected] ~]# innobackupex --apply-log /root/backup/2018-08-31_02-17-02/
4、开始恢复
[[email protected] ~]# innobackupex --copy-back /root/backup/2018-08-31_02-17-02/
[[email protected] ~]# chown -R mysql.mysql /var/lib/mysql/*
现在再来查看回复后的数据库,可以发现所有的数据都回来了。
注:其中--redo-only 的意义--> 在“准备基本完整备份” 和 “合并所有的增量备份(除了最后一个增备)”时使用此选项。它直接传递给xtrabackup的 xtrabackup --apply-log-only 选项,使xtrabackup跳过"undo"阶段,只做"redo"操作。如果后面还有增量备份应用到这个全备,这是必要的。
六、表分区
MySQL支持四种分区类型,分别为:
RANGE分区
LIST分区
HASH分区
KEY分区
1、range分区类型
该种分区类型是基于连续的值进行分区.
例如创建students表,并且基于id进行分区,id小于101,id小于201,id小于301的三个分区表。
([email protected]) [mydb1]> create table students (id INT,name char(20),grade float(3,1)) partition by range (id) ( partition p0 values less than (101),partition p1 values less than (201),partition p2 values less than (301) );
2、list分区类型
该种分区类型是基于离散的值进行分区。
例如创建cla***ooms表,其中room-id为11,12,13,14的在pfirst分区表,21,22,23,24的在psecond分区表,31,32,33,34的在pthird分区表。
([email protected]) [mydb1]> create table cla***ooms (id INT,leader char(20)) partition by list(id) ( partition pfirst values in (11,12,13,14),partition psecond values in (21,22,23,24),partition pthird values in (31,32,33,34) );
3、hash分区类型
该种分区类型是基于不同的值进行hash运算,再通过hash值进行分区。hash分区的键必须为整数。
例如创建teachers表,其中根据id字段值进行hash运算,语法格式为:partition by hash (expression) partitions num。expresssion表示一个返回整数的表达式,num表示分区的数量。
([email protected]) [mydb1]> create table teachers (id INT,name char(20),age TINYINT) partition by hash (id) partitions 3;
4、key分区类型
该种分区类型也是基于不同的值进行hash运算,和hash分区不同的是,key分区支持非整数的键。
([email protected]) [mydb1]> create table employee (name char(20),birthday date,job char(30)) partition by key (birthday) partitions 3;
以上是关于高性能MySQL总结的主要内容,如果未能解决你的问题,请参考以下文章