赞
踩
目录
2、binlog增长过快,mysql性能骤降如何优化?(性能优化)
在企业应用中,成熟的业务通常数据量都比较大,单台mysql在安全性、高可用性和高并发方面无法满足实际的需求,会需要配置多台主从数据库服务器、读写分离来实现mysql的高负载和高可用。
两个日志三个线程
1)statement 基于语句的复制(优点:执行效率高,占用空间小;缺点:无法保证在高并发高负载时候的精确度)
2)row 基于行的复制(优点:精确度高;缺点:执行效率低,占用空间大)
3)mixed 混合类型的复制(默认采用基于语句的复制,一旦发现基于语句无法保证精确复制时,就会采用基于行的复制)
基于二进制日志进行数据同步
关键词:两个日志,三个线程
主库 | 192.168.170.200 | 注意: 主从数据库版本相差不能大,建议使用一致的 |
从库1 | 192.168.170.101 | |
从库2 | 192.168.170.120 |
主从复制的配置步骤
1)主从服务器先做时间同步
2)修改主从数据库的配置文件,主库开启二进制日志,从库开启中继日志
3)在主库创建主从复制的用户,并授予主从复制的权限
4)在从库使用 change master to 对接主库,并 start slave 开启同步
5)在从库使用 show slave status\G 查看 IO线程和 SQL线程的状态是否都为 YES
注意:如果你使用克隆的方法得到三台mysql服务器,会存在uuid冲突问题导致主从复制实现不了,需要修改uuid。
- 初始化
- setenforce 0
- systemctl disable --now firewalld
- yum remove -y mariadb-libs.x86_64
-
- 安装MySQL。下载到opt目录中并解压,解压后的包重命名并移动到/usr/local目录中
- cd /opt/
- rm -rf *
- rz -E
- tar xf mysql-5.7.39-linux-glibc2.12-x86_64.tar.gz
- mv mysql-5.7.39-linux-glibc2.12-x86_64 /usr/local/mysql
-
- 创建程序用户管理并修改mysql目录和配置文件的权限
- useradd -s /sbin/nologin mysql
- chown -R mysql:mysql /usr/local/mysql
- 修改配置文件
- vim /etc/my.cnf
- chown mysql:mysql /etc/my.cnf
- ======================================================================================
- [client]
- port = 3306
- socket=/usr/local/mysql/mysql.sock
-
- [mysqld]
- user = mysql
- basedir=/usr/local/mysql
- datadir=/usr/local/mysql/data
- port = 3306
- character-set-server=utf8
- pid-file = /usr/local/mysql/mysqld.pid
- socket=/usr/local/mysql/mysql.sock
- bind-address = 0.0.0.0
- skip-name-resolve
- max_connections=2048
- default-storage-engine=INNODB
- max_allowed_packet=16M
- server-id = 1
- sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
- ======================================================================================
-
- 设置环境变量,申明/宣告mysql命令便于系统识别并初始化数据库
- echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
- source /etc/profile
- cd /usr/local/mysql/bin
- ./mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
-
- 设置系统识别,进行操作:
- cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
- chmod +x /etc/init.d/mysqld
- systemctl daemon-reload
- systemctl restart mysqld
- 初始化数据库密码:
- mysqladmin -u root -p password "123456"
-
- 登录数据库
- mysql -u root -p123456
- 创建用户并设置密码:
- CREATE USER 'root'@'%' IDENTIFIED BY '123456';
- 赋予远程连接的权限
- GRANT ALL PRIVILEGES ON *.* TO 'root'@'%';
- 刷新生效
- flush privileges;
- 修改加密方式,可以进行远程连接
- ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
- 时间同步操作
- 方式一:chrony自动同步时间,centOS7之后官方建议使用chrony
- 安装开启chrony程序
- yum install -y chrony
- systemctl start chronyd
- 修改chrony配置文件
- vim /etc/chrony.conf
- ====================================================================================
- 3 #server 0.centos.pool.ntp.org iburst
- 4 #server 1.centos.pool.ntp.org iburst
- 5 #server 2.centos.pool.ntp.org iburst
- 6 #server 3.centos.pool.ntp.org iburst
- 7 server ntp.aliyun.com iburst
- ====================================================================================
- 重启检查是否同步成功,210 Number of sources = 1表示同步成功
- systemctl restart chronyd
- chronyc sources
-
- 方式二:ntpd自动同步时间
- 查看是否安装,没有安装的话就yum安装一下ntpd服务,注意ntp与chrony端口号相同不要冲突
- rpm -q ntp
- yum install -y ntpd
- systemctl start ntpd
- 查看是否同步
- ntpd -p
-
- 方式三:ntpdate手动同步
- 查看是否安装,没有安装用yum安装即可
- rpm -q ntpdate
- 指定阿里云事件源服务器就会自动同步好
- ntpdate ntp.aliyun.com
- 查看ntp路径,计划任务中使用绝对路径
- which ntpdate
- 配合计划任务做每半小时自动同步
- crontab -e
- */30 * * * * /sbin/ntpdate ntp.aliyun.com &> /dev/null
生产环境中不可能所有服务器都连接外网,会有一台跳板机或边缘服务器既可以连接内网也可以连接外网,用ntp或者chrony同步时钟源服务器,然后内网服务器server连接到边缘服务器地址,把边缘服务器作为内网服务器的时钟源,从而实现时间同步。
如何搭建ntp时间服务器?
1、主机A做ntp服务器
①安装ntp服务
yum -y install ntp
②修改配置文件/etc/ntp.conf
#restrict default kod nomodify notrap nopeer noquery 注释此行内容 # nomodify 客户端不可以修改时间参数但是可以同步时间服务器,添加以下内容 restrict default nomodify 以下为 NTP服务默认的时间同步源,将其注释 #server 0.centos.pool.ntp.org iburst #server 1.centos.pool.ntp.org iburst #server 2.centos.pool.ntp.org iburst #server 3.centos.pool.ntp.org iburst 添加新的时间同步源 server time1.aliyun.com③开启ntpd服务,查看同步状态
systemctl start ntpd.service 查看ntp网络时间同步状态 ntpq -p remote refid st t when poll reach delay offset jitter ============================================================================== 203.107.6.88 10.165.84.13 2 u 28 64 1 15.767 708.472 0.0002、主机B做客户机
ntp服务器开启ntp服务后等待几分钟后,客户机再同步。
ntpdate 192.168.66.11 14 Feb 11:37:25 ntpdate[1453]: step time server 192.168.66.11 offset 0.880807 sec # 将命令放入计划任务即可 crontab -l */5 * * * * /usr/sbin/ntpdate 192.168.66.11 &>/dev/null
- 主库修改配置文件
- vim /etc/my.cnf
- -------------------------------------------------------------------------------------------
- server-id = 1 #确保id不与从库冲突
- log-bin=mysql-bin #添加,主服务器开启二进制日志
- binlog_format=mixed
- #以下为选配项
- expire_logs_days=7 #设置二进制日志文件过期时间,默认值为0,表示logs不过期
- max_binlog_size=500M #设置二进制日志限制大小,如果超出给定值,日志就会发生滚动,默认值是1GB
- skip_slave_start=1 #阻止从库崩溃后自动启动复制,崩溃后再自动复制可能会导致数据不一致的
- #"双1设置",数据写入最安全
- innodb_flush_log_at_trx_commit=1 #redo log(事务日志)的刷盘策略,每次事务提交时MySQL都会把事务日志缓存区的数据写入日志文件中,并且刷新到磁盘中,该模式为系统默认
- sync_binlog=1 #在进行每1次事务提交(写入二进制日志)以后,Mysql将执行一次fsync的磁盘同步指令,将缓冲区数据刷新到磁盘
- -------------------------------------------------------------------------------------------
- systemctl restart mysqld
-
- 登录数据库
- mysql -u root -p密码
- GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.170.%' IDENTIFIED BY '123456'; 给从服务器创建用户并授权
- FLUSH PRIVILEGES; #刷新二进制文件
- show master status; #查看主库当前使用的二进制日志和位置
关于“双1设置”
innodb_flus_log_at_trx_commit=1 sync_binlog=1“双1设置”数据写入最安全,每次事务提交都讲二进制日志和缓冲数据刷盘,双1设置适合数据安全性能要求非常高的业务,如订单付款之类的。但像大型电商活动,双1设置会成为系统性能瓶颈,推荐使用性能较快的设置,并使用带蓄电池后备电源防止系统断电异常。
innodb_flus_log_at_trx_commit=2 sync_binlog=500
- [root@localhost ~]# vim /etc/my.cnf
- [root@localhost ~]# systemctl restart mysqld.service
-
- 登录数据库
- mysql -u root -p123456
-
- 配置同步,注意 master_log_file 和 master_log_pos 的值要与主库上查询的一致
- change master to master_host='192.168.170.200',master_port=3306,master_user='myslave',master_password='myslave00',master_log_file='mysql-bin.000001',master_log_pos=777;
- 开启同步
- start slave;
报错:主从状态不是YES,这里是我的配置命令输错导致。想要重新设置master节点,做以下操作。
生产环境中用量大的话会经常出现主从复制延迟的问题,会导致客户在主服务器写入数据,但长期无法及时读取到最新的数据。
主从复制延迟如何判断?可能原因?解决方案?(故障案例)
【如何判断?】通过在从库执行show slave status\G命令,查看输出的Seconds_Behind_Master参数的值来判断,是否有发生主从延时。如果为正值表示主从已经出现延时,数字越大表示从库落后主库越多。
判断方法一:根据数据库中show slave status\G输出的second_behind_master的值为0表示延时;SQL_DELAY表示从库滞后多少秒。
判断方法二:第三方软件包mk-hearbeat(用的少,此方法略过)
【根本原因】主库可以并发多线程执行写入操作,而从库的SQL线程默认是单线程串行化复制,从库的复制效率可能会跟不上主库的写入速度。
【导致延迟的因素】master服务器高并发有大量事务;网络延迟;从库硬件设备导致;是同步复制而不是异步复制;慢SQL语句过多。
【解决方案】
主从复制不一致如何处理?(故障案例)【★★★】
业务繁忙的情况下且数据相差不大,先忽略错误做同步,然后找个不繁忙的时间锁一下数据库,重新做主从复制同步。重新做主从,完全同步。先进入主库,进行锁表防止数据写入。mysql> flush tabls...第二步,完全备份数据。第三步查看master状态。第四步,把mysql备份文件传导从库,进行数据恢复。第五步停止从库状态。第六步到从库执行mysql命令导入完全数据备份。第七步设置从库同步,注意该处的同步点。第八步重新开启从同步,查看同步状态。
异步复制:主库在执行完客户端提交的事务后就会立即响应给客户端
全同步复制:主库在执行完客户端提交的事务后,要等待所有从库返回都响应给主库,才会响应给客户端
半同步复制:主库在执行完客户端提交的事务后,只要等待至少一个从库返回响应给主库,就会响应给客户端。半同步复制兼顾性能和安全性,所以生产环境中一般都会选用半同步复制模式。
① 主数据库配置
- 修改配置文件,在 [mysqld] 区域添加下面内容
- vim /etc/my.cnf
- ......
- plugin-load=rpl_semi_sync_master=semisync_master.so #加载mysql半同步复制的插件
- rpl_semi_sync_master_enabled=ON #或者设置为"1",即开启半同步复制功能
- rpl-semi-sync-master-timeout=1000 #超时时间为1000ms,即1s
- 重启mysql
- systemctl restart mysqld
-
- 重新登录数据库
- mysql -u root -p123456
- 查看半同步复制开启状态和连接的客户机
- show status like '%Rpl_semi%';
② 从数据库配置
- vim /etc/my.cnf
- ......
- plugin-load=rpl_semi_sync_slave=semisync_slave.so
- rpl_semi_sync_slave_enabled=ON
- systemctl restart mysqld
③ 查看半同步是否在运行
- #主数据库执行
- show status like 'Rpl_semi_sync_master_status';
- show variables like 'rpl_semi_sync_master_timeout';
-
- #从数据库执行(此时可能还是OFF状态,需要在下一步重启IO线程后,从库半同步状态才会为ON)
- show status like 'Rpl_semi_sync_slave_status';
-
- #重启从数据库上的IO线程
- STOP SLAVE IO_THREAD;
- START SLAVE IO_THREAD;
参数说明:
Rpl_semi_sync_master_clients #半同步复制客户端的个数
Rpl_semi_sync_master_net_avg_wait_time #平均等待时间(默认毫秒)
Rpl_semi_sync_master_net_wait_time #总共等待时间
Rpl_semi_sync_master_net_waits #等待次数
Rpl_semi_sync_master_no_times #关闭半同步复制的次数
Rpl_semi_sync_master_no_tx #表示没有成功接收slave提交的次数
Rpl_semi_sync_master_status #表示当前是异步模式还是半同步模式,on为半同步
Rpl_semi_sync_master_timefunc_failures #调用时间函数失败的次数
Rpl_semi_sync_master_tx_avg_wait_time #事物的平均传输时间
Rpl_semi_sync_master_tx_wait_time #事物的总共传输时间
Rpl_semi_sync_master_tx_waits #事物等待次数
Rpl_semi_sync_master_wait_pos_backtraverse #可以理解为"后来的先到了,而先来的还没有到的次数"
Rpl_semi_sync_master_wait_sessions #当前有多少个session因为slave的回复而造成等待
Rpl_semi_sync_master_yes_tx #成功接受到slave事物回复的次数
当主库在半同步复制超时时间内(rpl_semi_sync_master_timeout)没有收到从库的响应,就会自动降为半同步复制。当主库发送完一个事务事件后,主库在超时时间内收到了从库的响应,就会又恢复为半同步复制。一主多从的架构中,如果要开启半同步复制,可以只把一台从库开启半同步复制。
【binlog增长过快可能带来的问题】:磁盘空间不足、性能下降;
【增长过快的原因】①大失误生成大量binlog记录 ②频繁的DDL操作 ③长时间的读事务 ④错误的参数配置,如max_binlog_size和expire_logs_days的设置
【解决方案】①拆分大事务 ②优化DDL操作,比如零碎的操作合并一条执行 ③增加binlog的回滚点,设置binlog的保留时长为3天,保存大小为1G等 ④定期清理和归档 ⑤将row改为statement模式,row最精确但很消耗空间
原理:在主库上处理事务性操作(写入操作),在从库上处理查询操作(读操作),再通过主从复制将主库上的数据同步给从库。
作用:通过读写分离可以分担数据库单节点的负载压力,提高数据库的读写性能
代码中根据select、insert 进行路由分类这类方法也是目前生产环境应用最广泛的。优点是性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支;缺点是需要开发人员来实现,运维人员无从下手。但是并不是所有的应用都适合在程序代码中实现读写分离,大型复杂的Java应用用代码实现读写分离对代码改动就较大。
代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库。
(1)MySQL-Proxy。MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行SQL 判断。
(2)Atlas。是由奇虎360的Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。
(3)Amoeba。由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。
(4)Mycat。是一款流行的基于Java语言编写的数据库中间件,是一个实现了MySql协议的服务器,其核心功能是分库分表。配合数据库的主从模式还可以实现读写分离。由于使用MySQL Proxy 需要写大量的Lua脚本,这些Lua并不是现成的,而是需要自己去写。这对于并不熟悉MySQL Proxy 内置变量和MySQL Protocol 的人来说是非常困难的。
Amoeba是一个非常容易使用、可移植性非常强的软件。因此它在生产环境中被广泛应用于数据库的代理层。
基于上面的主从复制部署案例,这里再添加一台服务器192.168.170.100 ,作为中间代理层,安装amoeba即可。
- yum remove java*
- java -version
- cd /opt/
- rm -rf /
- rz -E
- ls
- chmod +x jdk-6u14-linux-x64.bin
- ./jdk-6u14-linux-x64.bin
配置连接端口号以及amoeba的用户名
读操作是在从库完成的,写入是在主库写入的。怎么确定是在amoeba写入的数据呢?
关闭从库的slave,在客户端插入数据,主库能够看到插入了数据,但是从库是看不到的。
在两个从库插入数据,客户端查看的数据会是从库获取的,非主库;
innodb_buffer_pool_size=2048M #增大让更多操作在Mysql内存中完成,减少磁盘操作;
innodb_log_file_size=50M #此参数确定数据日志文件的大小,以M为单位,更大的设置可以提高性能。
innodb_log_files_in_group=3 #为提高性能,MySQL可以以循环方式将日志文件写到多个文件。推荐设置为3;
read_buffer_size=1M #MySQL 读入缓冲区大小。对表进行顺序扫描的请求将分配到一个读入缓冲区MySQL会为他分配一段内存缓冲区;
innodb_flush_log_at_trx_commit=1和sync_binlog=1 #双1设置,提高主库数据安全性;
innodb_flush_log_at_trx_commit=2和sync_binlog=0 #从库优化,提高性能;
expire_logs_days=7 #设置二进制日志文件过期时间,默认值为0,表示logs不过期;
max_binlog_size=500M #设置二进制日志限制大小,如果超出日志就会发生滚动,默认值是1GB;max_connect_errors #是一个MySQL中与安全有关的计数器值,他负责阻止过多尝试失败的客户端以防止暴力破解密码的情况,当超过指定次数,MySQL服务器将禁止host的连接请求,直到mysql服务器重启或通过flush hotos命令清空此host的相关信息。(与性能并无太大的关系)
max_allowed_packet=32M #根据配置文件限制server接受的数据包大小。
参数汇总: [mysqld] basedir = /usr/local/mysql datadir = /usr/local/mysql/data server_id = 1 socket = /usr/local/mysql/mysql.sock log-error = /usr/local/mysql/data/mysqld.err slow_query_log = 1 slow_query_log_file=/usr/local/mysql/data/slow-query.log long_query_time = 1 log-queries-not-using-indexes max_connections = 1024 back_log = 128 wait_timeout = 60 interactive_timeout = 7200 key_buffer_size = 256M query_cache_size = 256M query_cache_type = 1 query_cache_limit = 50M max_connect_errors = 20 sort_buffer_size = 2M max_allowed_packet = 32M join_buffer_size = 2M thread_cache_size = 200 innodb_buffer_pool_size = 2048M innodb_flush_log_at_trx_commit = 1 innodb_log_buffer_size = 32M innodb_log_file_size = 128M innodb_log_files_in_group = 3 log-bin=/usr/local/mysql/data/mysqlbin binlog_cache_size = 2M max_binlog_cache_size = 8M max_binlog_size = 512M expire_logs_days = 7 read_buffer_size = 1M read_rnd_buffer_size = 16M bulk_insert_buffer_size = 64M
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。