双重密码,MySQL8.0 创新特性

MySQL 8.0新特性专栏目录

双重密码,MySQL 8.0创新特性



前言:

MySQL 8.0 引入了很多令人振奋的新特性,跟账户认证相关的新特性包括:新增caching_sha2_password身份认证插件,支持角色,区分系统账户和普通账户,维护密码历史信息限制重复使用以前的密码和密码过期等,双重密码,生成随机密码,登录失败跟踪和临时锁定账户。

MySQL 8.0 最令人眼前一亮的特性:双重密码。这个特性在数据库领域应该也是第一次引入,为线上DB变更带来了极大的便利。


1. 双重密码 Dual Password

MySQL 8.0.14之后,账户允许拥有双重密码,一个主密码,一个备密码。客户端通过主密码或者备密码都可以正常连接到数据库,这个特性为我们线上DB的账户变更带来了极大的便利。即使在使用大量服务器或多个应用程序连接到不同 MySQL服务器的情况下,也可以无缝地执行数据库账户密码更改,而不影响业务连续性。在此之前,数据库账户只允许有一个密码,修改数据库账户密码之后,如果应用程序仍然以旧密码连接MySQL数据库,应用程序会一直报错。双重密码的出现完美地解决了这个问题。

1.1 适用场景

适用场景

  • 同一个服务使用相同账户密码连接了多个不同的数据库实例,其中某个数据库实例需要修改密码,修改密码前后服务访问不中断。
  • 多个不同服务使用相同账户密码连接了同一个数据库实例,其中某个服务需要修改数据库账户密码,修改密码前后服务访问不中断。

1.2 不停机修改数据库账户密码的具体过程

  1. 对于要更改的账户,建立一个新的主密码,原密码作为备密码。此时,MySQL
    Server会同时承认主密码和备密码,所有应用都可以继续用老的密码连进来。
  2. 一旦在数据库完成更新密码,应用可以使用新的密码连进来。
  3. 等所有应用迁移到新的主密码,备密码就可以去掉了(discard)。一旦被discard,就只能用新的密码连接数据库。

1.3 对比验证不停机修改密码(MySQL 8.0 vs MySQL 5.7)

验证一下MySQL8.0双重密码的功效。作为对比,使用同一段python小程序分别循环连接MySQL 8.0 和 MySQL 5.7实例,期间修改数据库密码,查看程序是否报错。

测试连接程序:mysql_connection.py

# -*- code: utf-8 -*-
'''
连接mysql操作数据库
'''
import pymysql
import time

class MysqlOperate(object):
    def __init__(self, **db_info):
        self.host = db_info.get('host')
        self.port = db_info.get('port')
        self.db = db_info.get('db')
        self.user = db_info.get('user')
        self.password = db_info.get('password')
        self.charset = 'utf8mb4' if not db_info.get('charset') else db_info.get('charset')
        self.connection = pymysql.connect(host=self.host,
                                          port=self.port,
                                          db=self.db,
                                          user=self.user,
                                          password=self.password,
                                          charset=self.charset,
                                          read_timeout=None)

    def close(self):
        self.connection.close()

# main
if __name__ == "__main__":
    mysql_info = {
    
    'host': '127.0.0.1', 'port': 3306, 'db': 'information_schema', 'user': 'user8', 'password': 'user8user8', 'charset': 'utf8'}
    i = 0
    while True:
        i += 1
        try:
            MysqlDb = MysqlOperate(**mysql_info)
            time.sleep(1)
            print('Retry ' + str(i) + ': user8 Connection succeeded.')
            MysqlDb.close()
        except:
            print('Retry ' + str(i) + ': user8 Connection failed.')
        finally:
            if i > 100:
            break

1.3.1 分别在MySQL8.0和5.7新建测试账户

# 分别在MySQL8.0和5.7新建测试账户
[[email protected]][(none)]> create user user8@'127.0.0.1' identified by 'user8user8';
[[email protected]][(none)]> grant select on *.* to user8@'127.0.0.1';

1.3.2 连接MySQL 5.7的python程序,DB端修改账户user8的密码之后,连接MySQL失败,程序报错。

# MySQL 5.7 一旦修改账户user8的密码,python程序连接MySQL失败,程序报错。
[[email protected]][(none)]> ALTER USER 'user8'@'127.0.0.1' IDENTIFIED BY 'newpassword8';

# 日志信息:
Retry 21: user8 Connection succeeded.
Retry 22: user8 Connection succeeded.
Retry 23: user8 Connection failed.
Retry 24: user8 Connection failed.
Retry 25: user8 Connection failed.
Retry 26: user8 Connection failed.

1.3.3 MySQL 8.0 修改账户user8的密码,新密码设置为主密码,旧密码降级为备密码,python程序连接MySQL正常,程序自始至终没有报错!

# MySQL 8.0 修改账户user8的密码,新密码设置为主密码,旧密码降级为备密码,python程序连接MySQL正常,程序没有报错。
[[email protected]][(none)]> ALTER USER 'user8'@'127.0.0.1' IDENTIFIED BY 'newpassword8' RETAIN CURRENT PASSWORD;

# 日志信息:
Retry 21: user8 Connection succeeded.
Retry 22: user8 Connection succeeded.
Retry 23: user8 Connection succeeded.
Retry 24: user8 Connection succeeded.
Retry 25: user8 Connection succeeded.
Retry 26: user8 Connection succeeded.

1.3.4 MySQL 8.0 废弃备密码之后,python程序连接MySQL失败,程序开始报错。

# MySQL 8.0 废弃备密码之后,python程序连接MySQL失败,程序报错。
[[email protected]][(none)]> ALTER USER 'user8'@'127.0.0.1' DISCARD OLD PASSWORD;

# 日志信息:
Retry 30: user8 Connection succeeded.
Retry 31: user8 Connection succeeded.
Retry 32: user8 Connection failed.
Retry 33: user8 Connection failed.
Retry 34: user8 Connection failed.
Retry 35: user8 Connection failed.
Retry 36: user8 Connection failed.

总结

以上,双重密码可以完美解决线上DB的密码变更过程中可能出现的连接失败风险,尤其是针对多个应用程序连接同一套MySQL实例或者同一套程序连接多个MySQL实例的场景。

猜你喜欢

转载自blog.csdn.net/wangzihuacool/article/details/123600045