MySQL 5.7最新版本的2个bug

摘要:
5.7中的新业务没有问题。虽然没有问题,但并不意味着没有问题。我有一个习惯,没事就浏览percona的博客,所以我在最新的GA版本5.7.17中看到了两个bug,所以我设置了一个环境来重现这个bug。环境:5.7.17,1主设备和从设备。接下来,复制第一个错误。一个从库是普通拷贝,即未启用多线程拷贝,而另一个从属库是多线程拷贝。

好久没写博客了,都长草了。新业务上了5.7没遇到什么问题,虽然没遇到什么问题,但不代表没有问题,我有个习惯就是没事就喜欢逛逛percona的Blog,于是看到目前最新GA版本5.7.17的2个bug,于是就搭建环境进行bug复现。目前知道的2个bug如下:

1. slave_parallel_workers > 0,也就是开启了多线程复制的时候如果有延时,那么Seconds_Behind_Master一直是0,不会变化,虽然这个参数不准确,但也是一个衡量指标。准确的复制延时判断的请看我前面的文章:主从复制延时判断

2. super_read_only开启的时候mysql库中的gtid_executed表会压缩失败,至于这个表是干嘛的请参考文章:MySQL 5.7中新增的表gtid_executed,看看是否解决了你的痛点,原文作者是姜承尧,但原作者的连接打不开了。

环境:5.7.17, 1主2从,下面进行第一个bug的复现,其中一个从库是普通复制,也就是没开启多线程复制,另外一个从库开启多线程复制。

首先用sysbench写入100w数据,然后在主库进行delete操作,模拟延时,然后查看区别。

sysbench --test=oltp --oltp-table-size=1000000 --oltp-read-only=off --init-rng=on --num-threads=16 --max-requests=0 --oltp-dist-type=uniform --max-time=1800 --mysql-user=root --mysql-socket=/data/mysql/3306/mysqltmp/mysql.sock --mysql-password=123 --db-driver=mysql --mysql-table-engine=innodb --oltp-test-mode=complex prepare 

普通复制:

mysql> show variables like '%parallel%';
+------------------------+----------+
| Variable_name          | Value    |
+------------------------+----------+
| slave_parallel_type    | DATABASE |
| slave_parallel_workers | 0        |
+------------------------+----------+
2 rows in set (0.00 sec)

mysql> 

多线程复制:

mysql> show variables like '%parallel%';
+------------------------+---------------+
| Variable_name          | Value         |
+------------------------+---------------+
| slave_parallel_type    | LOGICAL_CLOCK |
| slave_parallel_workers | 8             |
+------------------------+---------------+
2 rows in set (0.02 sec)

准备查看复制延时脚本:

for i in {1..1000};
do
    (
        mysql -uroot -p123 -h 192.168.0.20 -e "SHOW SLAVE STATUSG" | grep "Seconds_Behind_Master" | awk '{print "slave_1_not-multi-threaded-repl: " $2}' &
        sleep 0.1 ;
        mysql -uroot -p123 -h 192.168.0.30 -e "SHOW SLAVE STATUSG" | grep "Seconds_Behind_Master" | awk '{print "slave_2_multi-threaded-repl: " $2}' &
    );
    sleep 1;
done

让这个脚本跑起来,然后在主库删除数据,看复制延时的情况。然后在主库删除数据:

delete from sbtest where id>100;

运行脚本,查看复制延时情况,输出如下,可以看到开启了多线程复制的Seconds_Behind_Master一直为0,不会变化,而普通复制则显示延时了。

[root@dbserver-yayun-04 ~]# sh a.sh 
mysql: [Warning] Using a password on the command line interface can be insecure.
slave_1_not-multi-threaded-repl: 103
mysql: [Warning] Using a password on the command line interface can be insecure.
slave_2_multi-threaded-repl: 0
mysql: [Warning] Using a password on the command line interface can be insecure.
slave_1_not-multi-threaded-repl: 104
mysql: [Warning] Using a password on the command line interface can be insecure.
slave_2_multi-threaded-repl: 0
mysql: [Warning] Using a password on the command line interface can be insecure.
slave_1_not-multi-threaded-repl: 105
mysql: [Warning] Using a password on the command line interface can be insecure.
slave_2_multi-threaded-repl: 0
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql: [Warning] Using a password on the command line interface can be insecure.
slave_1_not-multi-threaded-repl: 106
slave_2_multi-threaded-repl: 0

Percona给的解决方法是:

SELECT PROCESSLIST_TIME FROM performance_schema.threads WHERE NAME = 'thread/sql/slave_worker' AND (PROCESSLIST_STATE IS NULL  or PROCESSLIST_STATE != 'Waiting for an event from Coordinator') ORDER BY PROCESSLIST_TIME DESC LIMIT 1;


下面进行super_read_only开启以后触发bug的复现:

1. 其中一个从库设置gtid_executed_compression_period=1,用来控制每执行多少个事务,对此表进行压缩,默认值为1000

2. super_read_only开启,超级用户都无法更改从库的数据。

3. 关闭log_slave_updates,如果开启,gtid_executed表不会实时变更,也不会压缩。(percona博客中开启了log_slave_updates也触发了bug,我认为是博客中有错误)

mysql> show variables like '%gtid_ex%';
+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| gtid_executed_compression_period | 1     |
+----------------------------------+-------+
1 row in set (0.01 sec)

mysql> show variables like '%log_slave_updates%';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| log_slave_updates | OFF   |
+-------------------+-------+
1 row in set (0.00 sec)

mysql> show variables like '%super%';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| super_read_only | ON    |
+-----------------+-------+
1 row in set (0.00 sec)

mysql> 

下面在主库运行sysbench进行压测,产生事务。

sysbench --test=oltp --oltp-table-size=100000 --oltp-read-only=off --init-rng=on --num-threads=16 --max-requests=0 --oltp-dist-type=uniform --max-time=1800 --mysql-user=root --mysql-socket=/data/mysql/3306/mysqltmp/mysql.sock --mysql-password=123 --db-driver=mysql --mysql-table-engine=innodb --oltp-test-mode=complex run

查看从库:

mysql> select count(*) from gtid_executed;
+----------+
| count(*) |
+----------+
|       93 |
+----------+
1 row in set (0.44 sec)

mysql> select count(*) from gtid_executed;
+----------+
| count(*) |
+----------+
|      113 |
+----------+
1 row in set (0.66 sec)

mysql> 

可以发现并没有压缩,一直在增加。
执行show engine innodb status可以看到有线程在压缩表的,但是没成功,在回滚

---TRANSACTION 10909611, ACTIVE 2 sec rollback
mysql tables in use 1, locked 1
ROLLING BACK 4 lock struct(s), heap size 1136, 316 row lock(s)
MySQL thread id 1, OS thread handle 140435435284224, query id 0 Compressing gtid_executed table

查看INNODB_TRX表,也能发现有事务在回滚。

mysql> select trx_id,trx_state,trx_operation_state,trx_isolation_level from information_schema.INNODB_TRX;
+-----------------+--------------+---------------------+---------------------+
| trx_id          | trx_state    | trx_operation_state | trx_isolation_level |
+-----------------+--------------+---------------------+---------------------+
| 10919604        | ROLLING BACK | rollback            | REPEATABLE READ     |
| 421910840085200 | RUNNING      | starting index read | REPEATABLE READ     |
+-----------------+--------------+---------------------+---------------------+
2 rows in set (0.00 sec)

看见现在表已经有很多记录了:

mysql> select count(*) from gtid_executed;
+----------+
| count(*) |
+----------+
|     2448 |
+----------+
1 row in set (0.00 sec)

mysql> 

关闭super_read_only

mysql> set global super_read_only=0;
Query OK, 0 rows affected (0.00 sec)

mysql> select count(*) from gtid_executed;
+----------+
| count(*) |
+----------+
|        2 |
+----------+
1 row in set (0.07 sec)

mysql> select count(*) from gtid_executed;
+----------+
| count(*) |
+----------+
|        2 |
+----------+
1 row in set (0.00 sec)

mysql> 

马上恢复正常了。

参考文章:

https://www.percona.com/blog/2017/02/08/mysql-super_read_only-bugs/
https://www.percona.com/blog/2017/01/27/wrong-seconds_behind_master-with-slave_parallel_workers-0/
http://keithlan.github.io/2017/02/15/gtid_practice/?utm_source=tuicool&utm_medium=referral

免责声明:文章转载自《MySQL 5.7最新版本的2个bug》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇APP漏洞自动化扫描专业评测报告在ServU配置ODBC过程记录(一)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

MySQL8服务无法启动,服务没有报告任何错误

MySQL8服务无法启动,服务没有报告任何错误 错误信息: 免安装版mysql-8.0.15-winx64.zip 按照教程来安装,解压,增加my.ini文件,修改文件内部的地址信息,配置环境变量path,新建data文件夹(注意这里,就是这个位置出错了),以管理员身份运行cmd初始化,mysqld -install,net start mysql,...

MYSQL数据库基础篇

MySQL基础入门 一、数据库1 数据库概念(了解) 1.1 什么是数据库 数据库就是用来存储和管理数据的仓库! 数据库存储数据的优先: l  可存储大量数据; l  方便检索; l  保持数据的一致性、完整性; l  安全,可共享; l  通过组合分析,可产生新数据。 数据库具有原子性,数据不可再分割! 1.2 数据库的发展历程 l  没有数据库,使用...

深入MySQL复制(一)

本文非常详细地介绍MySQL复制相关的内容,包括基本概念、复制原理、如何配置不同类型的复制(传统复制)等等。在此文章之后,还有几篇文章分别介绍GTID复制、半同步复制、实现MySQL的动静分离,以及MySQL 5.7.17引入的革命性功能:组复制(MGR)。 本文是MySQL Replication的基础,但却非常重要。对于MySQL复制,如何搭建它不是重...

MySQL结果集 数据查询(重点)

如下: SELECT * FROM product;-- 查询所有列 SELECT pro_id,pro_name FROM product;-- 查询指定列 SELECT pro_name AS '产品名称',price FROM product;-- 添加常量列 把pro_id改为“产品名称”(添加常量列只是显示这个名称,查询后还是...

关于mariadb远程连接授权的设置

1.首先配置允许访问的用户,采用授权的方式给用户权限 1 GRANTALLPRIVILEGESON*.* TO'root'@'%'IDENTIFIED BY'123456'WITHGRANTOPTION; 说明:root是登陆数据库的用户,123456是登陆数据库的密码,*就是意味着任何来源任何主机反正就是权限很大的样子。 2.最后配置好权限之后...

DorisSQL与MySQL函数对照 差异篇

## 1.日期函数### 时区.```mysql -> convert_tz(dt,from_tz,to_tz)doris -> CONVERT_TZ(DATETIME dt, VARCHAR from_tz, VARCHAR to_tz)```### 获取当前的日期,以DATE类型返回.```mysql -> CURDATE()dori...