千金良方:MySQL性能优化金字塔法则
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.4 升级注意事项

对于复制架构,在多版本混用的应用场景中,如果主库有低于MySQL 5.7版本的,则从库不建议升级到MySQL 5.7版本,否则容易出现莫名其妙的SQL线程报错。例如:

# 在主库中创建一个带有主键的InnoDB表(低于MySQL 5.7版本的库),针对主键字段设置为null(虽然这个例子不是很恰当,但这里仅限于说明从MySQL 5.6升级到MySQL 5.7需要谨慎,在同一个复制架构中不建议存在多个版本)
mysql> show create table test;
......
| test  | CREATE TABLE `test`(
  `id` int(10)unsigned NOT NULL,
  `test1` varchar(100)DEFAULT NULL,
  PRIMARY KEY(`id`),
  KEY `i_hash`(`test1`)USING HASH,
  KEY `i_test1`(`test1`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 |
......
1 row in set(0.00 sec)
mysql> select version();
+------------+
| version() |
+------------+
| 5.6.35-log |
+------------+
1 row in set(0.00 sec)
mysql> alter table test modify column id int(10)unsigned NULL;
Query OK, 0 rows affected(0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> show create table test;
......
| test  | CREATE TABLE `test`(
  `id` int(10)unsigned NOT NULL DEFAULT '0',
  `test1` varchar(100)DEFAULT NULL,
  PRIMARY KEY(`id`),
  KEY `i_hash`(`test1`)USING HASH,
  KEY `i_test1`(`test1`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 |
......
1 row in set(0.00 sec)
## 解析binlog查看
[root@localhost data]# mysqlbinlog -vv mysql-bin.000203
Warning: mysqlbinlog: unknown variable 'loose_default-character- set=utf8'
......
# at 120
#170629 23:24:52 server id 1073306 end_log_pos 259 CRC32 0x4c357229   Query  thread_id=1
exec_time=0 error_code=0
use `xiaoboluo`/*! */;
......
alter table test modify column id int(10)unsigned NULL
/*! */;
......
# 在主库中创建一个带有主键的InnoDB表(高于或等于MySQL 5.7版本的库),针对主键字段设置为null
mysql> show create table test;
......
| test  | CREATE TABLE `test`(
  `id` int(10)unsigned NOT NULL AUTO_INCREMENT,
  `test1` varchar(100)NOT NULL DEFAULT '0',
  `test2` varchar(100)NOT NULL DEFAULT '0',
  `test3` varchar(100)DEFAULT NULL,
  `test4` varchar(100)DEFAULT NULL,
  `test5` varchar(100)DEFAULT NULL,
  PRIMARY KEY(`id`),
  KEY `i_test3`(`test3`),
  KEY `i_test4`(`test3`, `test4`),
  KEY `i_hash`(`test5`)USING HASH,
  FULLTEXT KEY `f_test5_test5`(`test4`, `test5`)
)ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8 |
......
1 row in set(0.00 sec)
mysql> select version();
+------------+
| version() |
+------------+
| 5.7.17-log |
+------------+
1 row in set(0.00 sec)
mysql> alter table test modify column id int(10)unsigned NULL;
ERROR 1171(42000): All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead

从上面的结果(这里指的是执行alter table test modify column id int(10)unsigned NULL语句的结果)中可以看到,MySQL 5.7版本不允许对主键设置null属性操作,MySQL 5.6版本是允许对主键设置null属性操作的,但会在存储引擎内部自动忽略这个动作。虽然忽略了这个动作,但是这条语句却执行成功了,已经记录到binlog中。如果从库是MySQL 5.7,就会在SQL线程重放到这条SQL语句时报错:ERROR 1171(42000): All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead,类似于图2-1所示。

图2-1