Mysql主从异常及常见问题处理

一、生产环境主从同步异常或者数据不一致解决办法

到slave上查看

mysql> show slave status\G                                                
Slave_IO_Running: Yes
Slave_SQL_Running: No

此时状态证明IO线程正常,可以去拉去二进制日志,SQL线程不正常,也就是在中继日志中执行sql语句出现问题

解决方案

下面介绍两种解决方法

方法一:忽略错误后,继续同步

该方法适用于主从库数据相差不大,或者要求数据可以不完全统一的情况,数据要求不严格的情况

解决:

stop slave;
set global sql_slave_skip_counter =1;    #表示跳过一步错误,后面的数字可变
start slave;

再用mysql> show slave status\G 查看从状态

mysql> show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

现在主从同步状态正常了

方式二:重新做主从,完全同步,需要锁库锁表

该方法适用于主从库数据相差较大,或者要求数据完全统一的情况

解决步骤如下:

首先在主节点查看一下二进制日志变化,如下图可以看到主库一直在有数据频繁写入

mysql> show master status;
+----------------------+----------+--------------+------------------+--------------------------------------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                                |
+----------------------+----------+--------------+------------------+--------------------------------------------------+
| mysql-bin-log.001671 | 26501432 |              |                  | 68be451c-55a6-11e7-9df7-f09838ae7dd7:1-345487494 |
+----------------------+----------+--------------+------------------+--------------------------------------------------+
1 row in set (0.00 sec)

mysql> show master status;
+----------------------+----------+--------------+------------------+--------------------------------------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                                |
+----------------------+----------+--------------+------------------+--------------------------------------------------+
| mysql-bin-log.001671 | 26519327 |              |                  | 68be451c-55a6-11e7-9df7-f09838ae7dd7:1-345487512 |
+----------------------+----------+--------------+------------------+--------------------------------------------------+
1 row in set (0.00 sec)

mysql>

1、这时候如果可以类似于停服维护的话,可以进行锁表,防止数据写入,将库设为只读状态

mysql> flush tables with read lock;

2、进行数据备份

#把数据备份到mysql.bak.sql文件

mysqldump -uroot -p -hlocalhost > mysql.bak.sql

3、把mysql备份文件传到从库机器,进行数据恢复

4、停止从库状态

mysql> stop slave;

5、然后到从库执行mysql命令,导入数据备份

mysql> source /tmp/mysql.bak.sql

6,现在可以在主查看一下二进制日志与pos节点个数,然后使用change master重新设置从同步,注意该处的同步点,就是主库show master status信息里的| File| Position两项

7、重新开启slave

mysql> start slave;

8、查看同步状态

mysql> show slave status\G  
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

9、回到主库取消锁

UNLOCK TABLES;

10,业务恢复,正常

方式三:重新做主从,完全同步,不需要锁库锁表

这种方式就是全量备份的方式,一般生产数据库都会使用innobackupex或类似工具做全量备份,在这里使用此工具进行介绍,但是只对innodb支持

1、找到最近一次全量备份的文件,在文件里除了库信息,还有一个名为xtrabackup_binlog_info的文件,里面记录了备份之后的二进制日志文件以及Position节点个数

2、将全量备份的文件拷贝到从节点

3、恢复,恢复需要注意的是,mysql需要stop掉,mysql的数据目录需要清空,如果不放心可以将目录里的文件移动走,隐藏文件也需要,确保以上没问题之后,执行恢复命令

准备恢复:
innobackupex --defaults-file=/etc/my.cnf    --apply-log 目录名		#此目录名为在主库传过来的全量备份目录名称
恢复:
innobackupex --defaults-file=/etc/my.cnf   --copy-back 目录名		#此目录名为在主库传过来的全量备份目录名称

根据数据量大小,此过程会有些漫长,直到最后恢复完成之后,启动从节点的mysql

4、登录到数据库,使用change master命令重新设置从同步,注意该处的同步点,就是全量备份目录里xtrabackup_binlog_info的文件内记录的| File与 Position两项

5、开启slave

mysql> start slave;

6、查看同步状态

mysql> show slave status\G  
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

恢复完成。

二、生产环境Mysql连接量打满,导致连接Mysql失败问题解决

造成此问题的原因:

1、数据库并发量过高,Mysql的最大连接量配置偏低,导致连接遭到限制

2、后端操作完数据库没有及时close释放连接,并且mysql的timeout时间过长,导致数据库存在大量sleep进程,占用连接

第一种情况解决办法:

在不停库的过程中,更改Mysql的连接数量限制

1、查看当前设置的mysql连接量

mysql> show variables like ‘max_connections’; 

2、根据需求更改连接数

mysql> set global max_connections = 连接个数;	#根据具体场景需求

3、在配置文件也进行修改,防止后续重启之后,导致配置失效

# 修改最大连接数
max_connections=连接个数	#根据具体场景需求

第二种情况解决办法:

在不停库的过程中,更改Mysql的连接超时时长

#查看超时时间:
mysql> show variables like  '%timeout%';
#闲置连接的超时时间由wait_timeout控制、默认8小时。
mysql> set  global wait_timeout=时长		#根据具体场景需求

修改配置文件进行更改

wait_timeout=时长		#根据具体场景需求
interactive_timeout=时长		#根据具体场景需求

完成。

二、Mysql的二进制日志将空间打满,清理

1、登录到mysql,更改日志保留时间

mysql> show variables like '%log%';
mysql> set global expire_logs_days = 保存时间;		#根据具体情况修改

2、在配置文件中更改日志保留时间

expire_logs_days=保存时间		#根据具体情况修改

3、分析日志,清理不需要的日志

mysql> show binary logs;

4、删除指定日期之前的日志

#删除指定日期之前的bin log
mysql> PURGE MASTER LOGS BEFORE'2011-9-18 23:59:59';	#后面日期自定义
#下面的语句可以清除 7 天前的binlog
mysql> PURGE MASTER LOGS BEFOREDATE_SUB( NOW( ), INTERVAL 7 DAY);

完成。 

你可能感兴趣的:(数据库,数据库)