开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内,可以解决你的问题。加群请联系微信 liuaustin3 ,(共1790人左右 1 + 2 + 3 + 4 +5) 4群(290+),另欢迎 OpenGauss 的技术人员加入。
最近说来惭愧,有开始说mysql 5.6 的问题了,是在是无奈有一个项目古老且XX,大批的在用MySQL 5.6 这个版本的数据库,之前并未进行管理,但基于Enterprise 的数据库都管理的还可以,所以这个项目也就到了手里,然后我们提出从5,6升级数据库版本的问题,并提出升级后的各种利好,但在升级过程中,我们遇到了升级后,又降级回去的问题,这里和各位说说为什么,以及我们疏忽了什么。
首先需要说明MySQL5.6 中存在的一些问题,估计已经被很多人所忘记,这里先回顾一下MySQL5.6 的问题点
问题1 MySQL 5.6 更容易产生主从同步的问题,基于MYSQL 5.7 提出的并行复制的概念,允许复制时间并行应用,可以启用多个线程来完成原来单一线程完成的工作,基于MYSQL 5.7 以后的MYSQL 在复制延迟上有很多的改善。
问题2 MYSQL5.6 performance_schema的问题,主要是这个部分的性能你开销较大开启对性能负面影响大,所以在部分情况下,还在遵循MYSQL5.5 之前对于PF 的一些尽量关闭的方式来处理 MYSQL5.6的 PF。
问题3 BINLOG 复制容易出现数据复制的问题,基于MYSQL.5.7 基于这个问题,推出了 GTID 等方式来进行功能上的增强和为MYSQL 数据复制拓扑上的稳定性上做出的改善方案。
问题4 对于内存的管理和句柄的限制等问题,在MYSQL5.6还是一个问题,这样的问题导致MYSQL5.6 无法良好的支持高并发和工作负载较重的场景,相对于MYSQL5.7 来说。
基于从数据库的复制方式,数据一致性,内存管理,句柄管理高并发等问题,从MYSQL 5.6 升级到MYSQL 5.7 好处是非常多的,尤其到了MYSQL5.7 的后面版本。
但但但,为什么升级后,又回退了,这个就是今天要说的
1 升级前,开发与DB 进行了评估,忽略了MYSQL 5.6 与 MYSQL5.7 之间的语法的不同,以及一些配置的问题。
MYSQL 5.7
问题1 语句撰写的语法变化,在MySQL 5.6中存在大量不符合SQL语法的一些写法,比如下面的关于union all 与 limit 1 的写法在 MySQL 5.6中可以被接受,但是在MySQL 5.7 中无法被接受。相关此次项目数据库版本回退主要就是因为这个问题产生的回退。
mysql> create table table1 (id int primary key,name varchar(20));
on all
select * from table2 limit 1;
Query OK, 0 rows affected (0.01 sec)
mysql>
mysql>
mysql> create table table2 (id int primary key,name varchar(20));
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> insert into table1 (id,name) values (1,'system');
Query OK, 1 row affected (0.01 sec)
mysql> insert into table2 (id,name) values (2,'system2');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql>
mysql> select * from table1 limit 1
-> union all
-> select * from table2 limit 1;
ERROR 1221 (HY000): Incorrect usage of UNION and LIMIT
mysql> create table table1 (id int primary key,name varchar(20));
Query OK, 0 rows affected (0.02 sec)
mysql>
mysql>
mysql> create table table2 (id int primary key,name varchar(20));
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> insert into table1 (id,name) values (1,'system');
Query OK, 1 row affected (0.00 sec)
mysql> insert into table2 (id,name) values (2,'system2');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql>
mysql> select * from table1 limit 1
-> union all
-> select * from table2 limit 1;
+----+--------+
| id | name |
+----+--------+
| 1 | system |
+----+--------+
1 row in set (0.00 sec)
mysql> create table table1 (id int primary key,name varchar(20));
on all
mysql> explain select * from table1 limit 1 union all select * from table2 limit 1;
+----+--------------+------------+------+---------------+------+---------+------+------+-----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------+------------+------+---------------+------+---------+------+------+-----------------+
| 1 | PRIMARY | table1 | ALL | NULL | NULL | NULL | NULL | 1 | NULL |
| 2 | UNION | table2 | ALL | NULL | NULL | NULL | NULL | 1 | NULL |
| NULL | UNION RESULT | | ALL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+------------+------+---------------+------+---------+------+------+-----------------+
问题 2 大小写敏感的问题
我们可以从下面的文字中发现5.6 中同样的意思的文字,大小写不同,在查询中可以根据输入条件的大小写的不同来进行对应大小写字段的查询,但是在5.7中则查询的结果很mysql ,5.6的查询结果与POSTGRESQL很类似。
当然5.6可以调整与MySQL 5.7 一样的模式,可基于当时数据已经复制到5.7 同时应用程序也无法进行修改符号5.7的当时的模式,所以这也是导致升级失败的一个原因。
这里我们只需要在建立数据的时候将数据库设置为
CREATE DATABASE mydb CHARACTER SET utf8 COLLATE utf8_bin;
在导入数据即可,MYSQL5.7就可以和MYSQL5.6在大小写查询方面一致。
但基于当时数据已经灌入,无法在改变的问题,所以只好进行回退。
但问题1 部分是无法进行解决的,所以回退也是必然。
mysql>
mysql> insert into table1 (id,name) values (2,'System');
Query OK, 1 row affected (0.00 sec)
mysql> insert into table2 (id,name) values (3,'SYSTEM');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql>
mysql> select * from table1;
+----+--------+
| id | name |
+----+--------+
| 1 | system |
| 2 | System |
+----+--------+
2 rows in set (0.00 sec)
mysql> select * from table2;
+----+---------+
| id | name |
+----+---------+
| 2 | system2 |
| 3 | SYSTEM |
+----+---------+
2 rows in set (0.00 sec)
mysql> select * from table1 where name = 'system';
+----+--------+
| id | name |
+----+--------+
| 1 | system |
| 2 | System |
+----+--------+
2 rows in set (0.01 sec)
mysql> select @@version
-> ;
+-----------+
| @@version |
+-----------+
| 5.7.44 |
+-----------+
1 row in set (0.00 sec)
mysql> insert into table1 (id,name) values (3,'SYSTEM');
Query OK, 1 row affected (0.01 sec)
mysql> select * from table1 where name = 'System';
+----+--------+
| id | name |
+----+--------+
| 1 | system |
| 2 | System |
| 3 | SYSTEM |
+----+--------+
3 rows in set (0.00 sec)
mysql>
mysql> create table table1 (id int primary key,name varchar(20));
Query OK, 0 rows affected (0.01 sec)
mysql>
mysql> insert into table1 (id,name) values (1,'system');
Query OK, 1 row affected (0.00 sec)
mysql> insert into table1 (id,name) values (2,'System');
Query OK, 1 row affected (0.00 sec)
mysql> insert into table1 (id,name) values (3,'SYSTEM');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> select * from table1 where name = 'system';
+----+--------+
| id | name |
+----+--------+
| 1 | system |
+----+--------+
1 row in set (0.00 sec)
mysql> select * from table1 where name = 'SYSTEM';
+----+--------+
| id | name |
+----+--------+
| 3 | SYSTEM |
+----+--------+
1 row in set (0.00 sec)
mysql> select * from table1 where name = 'System';
+----+--------+
| id | name |
+----+--------+
| 2 | System |
+----+--------+
1 row in set (0.01 sec)
mysql> select @@version;
+-----------+
| @@version |
+-----------+
| 5.6.51 |
+-----------+
1 row in set (0.00 sec)
mysql>
总结:MySQL 5.x 到 MySQL 8 很多人都会抱着12万分的小心,进行迁移的测试和语法的测试,但MySQL 5.6 到 5.7 却大多认为比较简单,问题点少,此次的回退就是给粗心大意的人,当头一棒。