一文带你了解MySQL之用户和权限原理

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 在学习这一章节的时候,我们可以先了解一下SQL语言,SQL语言共分为四大类:数据查询语言DQL(Data QueryLanguage):select 等数据操纵语言DML(database manage language):insert update delete 等数据定义语言DDL(Data Definition Language): create drop alter runcate 等数据控制语言DCL(Data Control Language): grant revoke commit rollback 等本文会频繁使用到DCL 数据控制语言

一、访问控制

1.1 连接验证(阶段1)

当我们连接MySQL的时候,MySQL会以下面2点进行连接验证


通过提供的账号和密码来验证身份

验证账号是否锁定

服务首先检查凭据,然后检查账户的锁定状态。任一步骤失败都会拒绝访问,没有问题就接收连接。锁定状态记录在user表account_locked列中。

mysql> select user,account_locked from user;

+--------+----------------+

| user   | account_locked |

+--------+----------------+

| root   | N              |

| multis | N              |

| multis | N              |

| root   | N              |

+--------+----------------+

4 rows in set (0.00 sec)

1.2 允许的连接

下表展示了User和Host值在各种的组合下, user表适用于传入的连接


User Host 允许的连接

‘fred’ h1.example.net 来自h1.example.net的fred

‘’ ‘h1.example.net’ 来自h1.example.net的任何用户

‘fred’ ‘%’ 任何主机的fred

‘’ ‘’ 任何主机的任何用户

‘fred’ ‘%.example.net’ 从example.net的任何主机的fred

‘fred’ ‘x.example.net%’ 从x.example.net,从x.example.com等的任何主机的fred

‘fred’ ‘198.51.100.177’ 从ip198.51.100.177主机的fred

‘fred’ ‘198.51.100.%’ 从ip198.51.100C类网中任何主机的fred

‘fred’ '198.51.100.0/255.255.255.0 与前面相同

1.3 连接的优先级

当有多个匹配项时,需要确认使用哪个匹配项,按照以下的方式解决问题


当服务器将user表读入内存,它会对user表进行排序

客户端尝试连接时,服务器将按排序顺序浏览各行

服务器使用与客户端主机名和用户名匹配的第一行

排序顺序


优先Host进行排序,其次User

有具体文字比%更具有高优先级(127.0.0.1比localhost高)

示例一

要查看其工作原理,假设user 表如下所示:


+-----------+----------+-

| Host      | User     | ...

+-----------+----------+-

| %         | root     | ...

| %         | jeffrey  | ...

| localhost | root     | ...

| localhost |          | ...

+-----------+----------+-

读入到内存时,自动排序后的结果如下所示:


+-----------+----------+-

| Host      | User     | ...

+-----------+----------+-

| localhost | root     | ...

| localhost |          | ...

| %         | jeffrey  | ...

| %         | root     | ...

+-----------+----------+-


挡localhost 上的root用户连接mysql时候,这个时候会匹配| localhost | root |这个条目对应的权限。 其他条目虽然也满足, 但不会匹配它们对应的权限。


示例二


我们创建'test'@'%'和''@'192.168.79.140’两个用户,进行连接的优先级的测试


[root@mysql2 ~]# mysql -root-p123456

## 忽略部分登陆代码 ##

mysql> create user ''@'192.168.79.140' identified by '123456';

mysql> create user 'test'@'%' identified by '123456';

mysql> select host,user from user;

+----------------+------+

| host           | user |

+----------------+------+

| %              | test |

| 192.168.79.140 |      |

| localhost      | root |

+----------------+------+

3 rows in set (0.00 sec)

mysql> exit;


使用我们刚才创建的'test'@'%'用户登录mysql


[root@mysql2 ~]# mysql -utest -p123456 -h192.168.79.140

按照mysql连接的优先级,用户在登陆mysql时,mysql读入到内存自动排序后的结果应如下所示:


+----------------+------+

| host           | user |

+----------------+------+

| 192.168.79.140 |      |

| localhost      | root |

| %              | test |

+----------------+------+


当前登录的'test'@'%'用户匹配连接是| 192.168.79.140 | |,我们可以通过CURRENT_USER()函数查验证当前用户是否匹配| 192.168.79.140 | |


mysql> select current_user();

+-----------------+

| current_user()  |

+-----------------+

| @192.168.79.140 |

+-----------------+

1 row in set (0.00 sec)

验证结果如我们推测一致,正式坏境中建议不要创建有不带用户名只有主机的用户。


1.4 请求验证(阶段二)

MySQL建立连接后,服务器进入访问控制的第二阶段。该连接发出的每个请求,会检查是否具有足够的权限,这些权限对应着如下这些表:


user 用户(全局)

db 数据库

tables_priv 表

columns_priv 列

procs_priv 存储过程

proxies_priv代理用户权限


二、用户管理

在这里我们需要知道的是mysql的用户名和主机名在一起才是一个有效的用户


2.1 新增用户

MySQL的语法和Oracle是相似的,如下


create user 'user'@'localhost' identified by 'passwd' [ACCOUNT UNLOCK]


ACCOUNT UNLOCK 用户默认是没有锁定的,如果用户锁定,我们登录的用户不会有第二阶段的请求验证。


我们创建一个本地可以登陆的multis用户,该用户默认是未锁定的状态。


mysql> create user 'multis'@'localhost' identified by '123456';

Query OK, 0 rows affected (0.00 sec)

2.2 用户修改

MySQL是可以通过数据操纵语言DML和数据定义语言DDL来进行修改的


2.2.1 使用DDL语言修改用户

我们查询当前数据库所有的用户名、主机和用户的状态


mysql> select user,host,account_locked from user;

+--------+-----------+----------------+

| user   | host      | account_locked |

+--------+-----------+----------------+

| root   | localhost | N              |

| multis | localhost | N              |

+--------+-----------+----------------+

2 rows in set (0.00 sec)


1、我们使用alter修改'multis'@'localhost'用户状态为锁定状态


mysql> alter user 'multis'@'localhost' account lock;

Query OK, 0 rows affected (0.00 sec)

mysql> select user,host,account_locked from user;

+--------+-----------+----------------+

| user   | host      | account_locked |

+--------+-----------+----------------+

| root   | localhost | N              |

| multis | localhost | Y              |

+--------+-----------+----------------+

2 rows in set (0.00 sec)


重新打开一个窗口进行mysql登陆,登陆的时候,MySQL报错ERROR 3118 (HY000): Access denied for user 'multis'@'localhost'. Account is locked.帐号被锁定,用户被拒绝访问。


[root@mysql2 ~]# mysql -umultis -p

Enter password:

ERROR 3118 (HY000): Access denied for user 'multis'@'localhost'. Account is locked.

2、我们使用alter修改'test'@'localhost'用户的密码


mysql> alter user 'test'@'localhost' identified by '654321';

Query OK, 0 rows affected (0.01 sec)

我们登陆'test'@'localhost'用户验证


[root@mysql2 ~]# mysql -utest -p654321

## 省略部分登陆提示 ##

mysql>


'test'@'localhost'用户使用修改后密码登陆成功


2.2.2 DML语句管理mysql用户

我们也可以直接更新mysql.user表的信息,进行用户的管理,但是需要flush privileges,将内存和磁盘中的数据保持一致。


1、修改'multis' @'localhost'用户用户名为multis1


mysql> update mysql.user set user = 'multis1' where user = 'multis' and host='localhost';

Query OK, 1 row affected (0.01 sec)

Rows matched: 1  Changed: 1  Warnings: 0

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

查询mysql.user表,进行校验


mysql> select user,host from mysql.user;

+---------+-----------+

| user    | host      |

+---------+-----------+

| multis1 | localhost |

| root    | localhost |

+---------+-----------+

2 rows in set (0.00 sec)

2、修改'multis1' @'localhost'用户host为127.0.0.1


mysql> update mysql.user set host = '127.0.0.1' where user = 'multis1' and host='localhost';

Query OK, 1 row affected (0.00 sec)

Rows matched: 1  Changed: 1  Warnings: 0

我们不刷新flush privileges,查询'multis1' @'localhost'用户信息


mysql> select user,host from mysql.user;

+---------+-----------+

| user    | host      |

+---------+-----------+

| multis1 | localhost |

| root    | localhost |

+---------+-----------+

2 rows in set (0.00 sec)


发现虽然更改了host,但是还以前的host,我们flush privileges后,继续查询'multis1' @'localhost'用户信息


mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)

mysql> select user,host from mysql.user;

+---------+-----------+

| user    | host      |

+---------+-----------+

| multis1 | 127.0.0.1 |

| root    | localhost |

+---------+-----------+

2 rows in set (0.00 sec)


2.3 删除用户

方法一:drop user


mysql> create user 'test'@'localhost' identified by '123456' account unlock;

Query OK, 0 rows affected (0.00 sec)

mysql> drop user 'test'@'localhost';

Query OK, 0 rows affected (0.00 sec

方案二:delete

mysql> create user 'test'@'localhost' identified by '123456' account unlock;

Query OK, 0 rows affected (0.00 sec)

mysql> delete from mysql.user where user = 'test' and host='localhost';

Query OK, 1 row affected (0.00 sec)

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)


某个用户已经被我们删除了,但是已经通过该用户连接进来的是不受影响的。那么如何清理掉这些用户,断开连接呢?


查询已经删除用户id,生成SQL


mysql> select concat('kill ',id,';') from information_schema.processlist where user='root' into outfile '/tmp/kill.sql';

ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement


报错原因: 没有指定secure_file_priv参数

解决方法: secure_file_priv是MySQL中的一个系统变量,用于限制LOAD DATA INFILE和SELECT … INTO OUTFILE语句的文件读写权限。它指定了允许从哪个目录中读取或写入文件。开启secure_file_priv参数,须在配置文件中修改,并重启数据库。


查询secure_file_priv参数,当前参数值为null


mysql> select @@secure_file_priv;

+--------------------+

| @@secure_file_priv |

+--------------------+

| NULL            |

+--------------------+

1 row in set (0.00 sec)

我们可以在my.cnf文件中指定:


[mysqld]

secure_file_priv=/tmp/

也可以通过命令来实时修改,可以随时生效而且永久生效(MySQL 8.0 推荐使用):


mysql> set persist secure_file_priv=/tmp/;

Query OK, 0 rows affected (0.00 sec)


重新查询secure_file_priv参数,当前参数值为/tmp/


mysql> select @@secure_file_priv;

+--------------------+

| @@secure_file_priv |

+--------------------+

| /tmp/              |

+--------------------+

1 row in set (0.00 sec)


继续查询清理的用户id,生成SQL


mysql> select concat('kill ',id,';') from information_schema.processlist where user='root' into outfile '/tmp/kill.sql';

Query OK, 1 row affected (0.00 sec)

mysql> source /tmp/kill.sql


OK,已删除的用户就已断开


2.4 查看用户

2.4.1 show create user 显示用户非权限属性

mysql> create user test@'localhost' identified by '123456';

Query OK, 0 rows affected (0.00 sec)

mysql> show create user 'test'@'localhost' \G;

*************************** 1. row ***************************

CREATE USER for test@localhost: CREATE USER 'test'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK

1 row in set (0.00 sec)

ERROR:

No query specified

微信图片_20230526000255.png

2.4.2 select * from mysql.user 查看已经创建的用户

mysql> select * from mysql.user where user='test' and host='localhost' \G;

*************************** 1. row ***************************

                Host: localhost

                 User: test

          Select_priv: N

          Insert_priv: N

          Update_priv: N

          Delete_priv: N

          Create_priv: N

            Drop_priv: N

          Reload_priv: N

        Shutdown_priv: N

         Process_priv: N

            File_priv: N

           Grant_priv: N

      References_priv: N

           Index_priv: N

           Alter_priv: N

         Show_db_priv: N

           Super_priv: N

Create_tmp_table_priv: N

     Lock_tables_priv: N

         Execute_priv: N

      Repl_slave_priv: N

     Repl_client_priv: N

     Create_view_priv: N

       Show_view_priv: N

  Create_routine_priv: N

   Alter_routine_priv: N

     Create_user_priv: N

           Event_priv: N

         Trigger_priv: N

Create_tablespace_priv: N

             ssl_type:

           ssl_cipher:

          x509_issuer:

         x509_subject:

        max_questions: 0

          max_updates: 0

      max_connections: 0

 max_user_connections: 0

               plugin: mysql_native_password

authentication_string: *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9

     password_expired: N

password_last_changed: 2023-04-18 22:00:36

    password_lifetime: NULL

       account_locked: N

1 row in set (0.00 sec)

ERROR:

No query specified


2.4.3 select current_user() 查看当前登录用户

mysql> select current_user;

+----------------+

| current_user   |

+----------------+

| root@localhost |

+----------------+

1 row in set (0.00 sec)

mysql> select user();

+----------------+

| user()         |

+----------------+

| root@localhost |

+----------------+

1 row in set (0.00 sec)

三、密码管理

3.1 修改密码(最终版)

3.1.1 alter修改密码(推荐使用)

mysql> alter user 'test'@'localhost' identified by '654321';

Query OK, 0 rows affected (0.01 sec)

3.1.2 mysqladmin修改密码

[root@mysql2 ~]# mysqladmin -utest -p654321 password

mysqladmin: [Warning] Using a password on the command line interface can be insecure.

New password:

Confirm new password:

Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.

3.1.3 set password修改密码

1 、使用默认加密


mysql> set password for 'test'@'%' ='abcdefg';

Query OK, 0 rows affected (0.01 sec)


2、使用PASSWORD()函数加密(mysql使用该方式进行密码加密)


mysql> set password for 'test'@'%' =password('123456');

Query OK, 0 rows affected (0.01 sec)


3.1.4 update(不推荐使用)

mysql> update mysql.user set authentication_string=password('Aroot123#') where user='dba';

Query OK, 0 rows affected, 1 warning (0.00 sec)

Rows matched: 0  Changed: 0  Warnings: 1

mysql> flush privileges;

Query OK, 0 rows affected (0.00 sec)


3.1.5 修改当前登录用户密码

mysql> alter user current_user() identified by '123456';

Query OK, 0 rows affected (0.00 sec)

mysql> alter user user() identified by '123456';

Query OK, 0 rows affected (0.00 sec)


3.2 密码策略

在设置密码策略时 identified by 'password' 可以忽略


3.2.1 密码过期策略

MySQL版本5.7.4版本起,可以通过全局变default_password_lifetime来设置全局的密码过期策略。主要有以下四种策略


1、密码立即过期策略 PASSWORD EXPIRE


ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

重置密码后才能正常登陆


我们修改'test'@'localhost'用户密码立即过期,查询改用户的非权限属性


mysql> alter user 'test'@'localhost' identified by '123456' password expire;

Query OK, 0 rows affected (0.00 sec)

mysql> show create user 'test'@localhost \G;

*************************** 1. row ***************************

CREATE USER for test@localhost: CREATE USER 'test'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' REQUIRE NONE PASSWORD EXPIRE ACCOUNT UNLOCK

1 row in set (0.00 sec)

ERROR:

No query specified


我们可以发现密码策略从PASSWORD EXPIRE DEFAULT变为PASSWORD EXPIRE,我们重新登陆mysql,发现使用sql语句时无法使用,提示在执行该语句之前,必须使用ALTER USER语句重置密码


mysql> select current_user();

ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

使用root用户修改'test'@'localhost'用户密码


mysql> alter user 'test'@'localhost' identified by '123456';

Query OK, 0 rows affected (0.01 sec)


密码修改完成后,可以正常登陆mysql


[root@mysql2 ~]# mysql -utest -p123456

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

+--------------------+

1 row in set (0.00 sec)

OK,测试完成


2、密码从不过期策略 PASSWOD EXPIRE NEVER


mysql> alter user 'test'@'localhost' identified by '123456' password expire;

Query OK, 0 rows affected (0.00 sec)


当前 'test'@'localhost' 用户永不过期。

3、指定过期时间策略 PASSWORD EXPIRE INTERVAL 90 DAY


mysql> alter user 'test'@'localhost' password expire interval 90 day;

Query OK, 0 rows affected (0.00 sec)


当前 'test'@'localhost' 用户90天以后过期,过期后需要我们修改 'test'@'localhost' 密码。


4、默认过期时间策略 PASSWORD EXPIRE DEFAULT


创建用户时,mysql默认的是该策略PASSWORD EXPIRE DEFAULT ,由default_password_lifetime参数决定密码的有效期。

可以使用 select @@default_password_lifetime或者show variables like '%default_password_lifetime%'进行查询


mysql> select @@default_password_lifetime;

+-----------------------------+

| @@default_password_lifetime |

+-----------------------------+

|                           0 |

+-----------------------------+

1 row in set (0.00 sec)


我们修改 'test'@'localhost'为默认时间过期


mysql> alter user 'test'@'localhost' password expire default;

Query OK, 0 rows affected (0.01 sec)


如果需要修改全局参数,我们可以在my.cnf文件中指定:


[mysqld]

default_password_lifetime=180


default_password_lifetime=180 密码有效期为6个月,最大值65535

default_password_lifetime=0 默认是0,密码永不过期


也可以通过命令来实时修改,可以随时生效而且永久生效(mysql 8.0版本支持,推荐使用):


mysql> set default_password_lifetime=180;

Query OK, 0 rows affected (0.00 sec)

我们现在要求每90天更改一次密码,我们可以create user和alter user...password expire interval 90 day


mysql> create user 'test1'@'localhost' identified by '123456' password expire interval 90 day;

Query OK, 0 rows affected (0.00 sec)


我们需要注意的是,当我们指定了用户的是密码立即失效、永久生效和指定过期间隔策略都会覆盖该语句命名的用户的全局策略。当指定用户默认过期时间,用户将会遵循全局密码策略。


当密码过期,我们可以通过修改密码,处理密码过期;下面进行测试


我们创建一个用户,默认策略是全局参数


mysql> create user 'test3'@'localhost' identified by '123456';

Query OK, 0 rows affected (0.00 sec)

mysql> show create user 'test3'@'localhost';

+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

| CREATE USER for test3@localhost                                                                                                                                           |

+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

| CREATE USER 'test3'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK |

+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)


修改当前用户立即失效


mysql> alter user 'test3'@'localhost' password expire;

Query OK, 0 rows affected (0.00 sec)

打开新的窗口登陆mysql,查询数据


[root@mysql2 ~]# mysql -utest3 -p123456

## 忽略登陆部分 ##

mysql> show databases;

ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

mysql>

系统提示修改密码


mysql> alter user 'test3'@'localhost' identified by '123456';

Query OK, 0 rows affected (0.00 sec)

重新登陆mysql


[root@mysql2 ~]# mysql -utest3 -p123456

## 忽略登陆部分 ##

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

+--------------------+

1 row in set (0.00 sec)


经过上面测试,我们得知修改密码,可以处理密码过期


3.2.2 密码复杂度策略

MySQL5.6.6版本之后增加了密码强度验证插件validate_password,相关参数设置的较为严格。使用了该插件会检查设置的密码是否符合当前设置的强度规则,若不满足则拒绝设置。默认没有安装这个插件,我们可以通过 select * from mysql.plugin 或者使用show variables like '%validate_password%'查看列表为空


mysql> select * from mysql.plugin;

Empty set (0.00 sec)

mysql> show variables like '%validate_password%';

Empty set (0.00 sec)

我们可以使用命令install plugin validate_password soname 'validate_password.so'进行安装


mysql> install plugin validate_password soname 'validate_password.so';

Query OK, 0 rows affected (0.00 sec)


mysql> SHOW VARIABLES LIKE 'vali%';

+--------------------------------------+--------+

| Variable_name                        | Value  |

+--------------------------------------+--------+

| validate_password_check_user_name    | OFF    |

| validate_password_dictionary_file    |        |

| validate_password_length             | 8      |

| validate_password_mixed_case_count   | 1      |

| validate_password_number_count       | 1      |

| validate_password_policy             | MEDIUM |

| validate_password_special_char_count | 1      |

+--------------------------------------+--------+

7 rows in set (0.01 sec)

而关闭密码复杂度使用改命令uninstall plugin validate_password


mysql> uninstall plugin validate_password;

Query OK, 0 rows affected (0.00 sec)

mysql> SHOW VARIABLES LIKE 'vali%';

Empty set (0.00 sec)

也可以在my.cnf配置文件中指定plugin-load=validate_password.so开启密码复杂度


[mysqld]

plugin-load=validate_password.so

关闭密码复杂度在my.cnf配置文件中指定validate-password=off重启服务即可。


[mysqld]

plugin-load=validate_password.so

validate-password=off


建议使用install plugin validate_password soname 'validate_password.so'和uninstall plugin validate_password进行密码复杂度的开启和关闭


我们通过查询,知道密码复杂度有


validate_password_check_user_name 用户名检测,检测是否重名,默认关闭


validate_password_dictionary_file 字典文件,字典文件中存在的密码不得使用


validate_password_length 密码的最小长度,此处为8


validate_password_mixed_case_count 至少要包含小写或大写字母的个数,此处为1


validate_password_number_count 至少要包含的数字的个数,此处为1


validate_password_policy 密码安全策略 0~2,默认MEDIUM(2)


LOW OR 1: 只限制长度

MEDIUM OR 2: 限制长度、数字、字母、特殊字符

STRONG OR 3: 限制长度、数字、字母、特殊字符、字典


validate_password_special_char_count 至少要包含的字符的个数,此处为1


我们使用set global 进行全局变量设置密码复杂度策略调为STRONG(3),从8开始,可通过SET PERSIST命令将全局变量的修改持久化到配置文件中。我们开始测试


mysql> set global validate_password_policy=2;

Query OK, 0 rows affected (0.00 sec)

首先我们创建密码字典文件


[root@mysql2 ~]# echo 'admin'> /tmp/dic.file

[root@mysql2 ~]# cat /tmp/dic.file

admin

使用set global指定字典文件


mysql> set global validate_password_dictionary_file ='/tmp/dic.file';

Query OK, 0 rows affected (0.00 sec)

我们查询密码复杂度策略


mysql> SHOW VARIABLES LIKE 'vali%';

+--------------------------------------+---------------+

| Variable_name                        | Value         |

+--------------------------------------+---------------+

| validate_password_check_user_name    | OFF           |

| validate_password_dictionary_file    | /tmp/dic.file |

| validate_password_length             | 8             |

| validate_password_mixed_case_count   | 1             |

| validate_password_number_count       | 1             |

| validate_password_policy             | STRONG        |

| validate_password_special_char_count | 1             |

+--------------------------------------+---------------+

我们进行密码的最小长度,大小写字母,符号,字典等方面进行测试,如下


--密码长度6位

mysql> alter user 'test3'@'localhost' identified by '123456';

ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

--密码长度8位

mysql> alter user 'test3'@'localhost' identified by '12345678';

ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

--密码长度10位,包含大小写字母各1位

mysql> alter user 'test3'@'localhost' identified by 'A12345678a';

ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

--密码长度11位,包含大小写字母符号各1位,成功

mysql> alter user 'test3'@'localhost' identified by 'A12345678a#';

Query OK, 0 rows affected (0.00 sec)

--密码字母包含在字典里面,失败

mysql> alter user 'test3'@'localhost' identified by 'Admin123456#';

ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

OK,测试成功,我们关闭密码复杂度策略

mysql> uninstall plugin validate_password ;

Query OK, 0 rows affected (0.00 sec)

3.2.3 密码必要验证策略(MySQL 8.0 新特性)

在MySQL 8.0 之前的版本,普通用户可以直接更改自己密码,不需要旧密码验证,也不需要知会管理员,比如用户test 需要更改密码,在MySQL 5.7 下直接敲alter user 命令即可,假设test在服务器上登陆数据库过后,忘记退出,test2用户刚好到服务器上修改密码。为了防止这类不安全事件的生,MySQL 8.0 发布了一系列密码验证策略。


密码必要验证策略password_require_current 也就是修改密码前必须验证密码


我们可以在my.cnf文件中指定:


[mysqld]

password_require_current =on

也可以通过命令来实时修改,可以随时生效而且永久生效(推荐使用):

mysql> set persist password_require_current=on;

Query OK, 0 rows affected (0.00 sec)

我们通过show variables like 'password%'命令来查询参数是否生效:

mysql> show variables like 'password%';

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| password_require_current | ON    |

+--------------------------+-------+

1 rows in set (0.01 sec)

可以在通过create user 和 alter user...password require current optional或者 password require current default 来覆盖全局参数的值,但是注意的是password require current default参数取决于require current optional参数的值

mysql> create user 'test'@'localhost' identified by '123456' password expire never password require current;

Query OK, 0 rows affected (0.01 sec)

登陆刚才创建的'test'@'localhost'用户登录,并修尝试的是该改密码

[root@mysql2 ~]# mysql -utest -p123456 -S /data/mysql/my3307/mysql.sock

## 省略部分登陆代码 ##

Server version: 8.0.32 MySQL Community Server - GPL

mysql> alter user user() identified by '654321';

ERROR 3892 (HY000): Current password needs to be specified in the REPLACE clause in order to change it.

当前密码需要在REPLACE子句中指定,以便更改它。接下来,alter user 跟上子句replace 来让'test'@'localhost'用户输入旧密码,成功更改新密码

mysql> alter user user() identified by '123456' replace '123456';

Query OK, 0 rows affected (0.01 sec)

我们使用alter user...password require current optional来关闭'test1'@'localhost'用户的密码必要验证策略

mysql>alter 'test1'@'localhost' password require current optional;

Query OK, 0 rows affected (0.01 sec)

接下来 'test1'@'localhost'用户又恢复为MySQL旧版本的安全行为

mysql> alter user user() identified by '123456';

Query OK, 0 rows affected (0.01 sec)


OK,测试完成


3.2.4 密码的重复使用策略(MySQL 8.0 新特性)

MySQL 8.0允许对重用以前的密码进行限制。 可以根据密码更改次数,已用时间或两者来确定重用限制。 可以在全局建立重用策略,并且可以将个人帐户设置为遵循全局策略或使用指定的某个帐户行为来覆盖全局策略。


帐户的密码历史记录包含着过去分配的密码。 MySQL可以限制从此历史记录中选择新密码,我们可以查询mysql.password_history,记录的密码更改的历史


如果根据密码更改次数限制帐户,则无法从指定数量的最新密码中选择新密码。 例如,如果密码更改的最小数量设置为3,则新密码不能与最近最新的3个密码相同。


如果根据已用时间限制帐户,则无法从历史记录中比指定天数更新的密码中选择新密码。 例如,如果密码重用间隔设置为60,则新密码不能和过去60天内的密码相同。


如果根据已用时间限制帐户和密码更改次数限制,则两个参数都需要满足才可以更改密码


注:空密码不会算在密码历史记录中。想要设置密码重用策略,可以通过设置password_history 和password_reuse_interval系统变量来实现: 默认都是0,即不启用重用密码策略。


最近使用的密码保留次数 password_history

最近使用的密码保留天数 password_reuse_interval


我们可以在my.cnf文件中指定:


[mysqld]

password_history=3

password_reuse_interval=30

也可以通过命令来实时修改,可以随时生效而且永久生效(推荐使用):

mysql> set persist password_history=3;

Query OK, 0 rows affected (0.00 sec)

mysql> set persist password_reuse_interval=30;

Query OK, 0 rows affected (0.00 sec)

我们通过show variables like 'password%'命令来查询参数是否生效:

mysql> show variables like 'password%';

+--------------------------+-------+

| Variable_name            | Value |

+--------------------------+-------+

| password_history         | 3     |

| password_require_current | ON    |

| password_reuse_interval  | 30    |

+--------------------------+-------+

3 rows in set (0.01 sec)

可以在通过create user 和 alter user...password history 3 password reuse interval 30 来覆盖全局参数的值

mysql> create user 'test4'@'localhost' identified  by '123456' password history 3 password reuse interval 30 day;

Query OK, 0 rows affected (0.00 sec)

我们可以使用命令show create user命令查询'test4'@'localhost'用户的非权限属性,可以发现PASSWORD HISTORY 3 PASSWORD REUSE INTERVAL 30 DAY,用户策略覆盖了全局策略

mysql> show create user 'test4'@'localhost' \G;

*************************** 1. row ***************************

CREATE USER for test4@localhost: CREATE USER `test4`@`localhost` IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$IPDZ.elS9pULZ|sjDgdLpKcyNUdLk2LZ7VfI9T6y56gc79nD2zOTB9xF5' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK PASSWORD HISTORY 3 PASSWORD REUSE INTERVAL 30 DAY PASSWORD REQUIRE CURRENT DEFAULT

1 row in set (0.00 sec)

还原到全局配置:

mysql> alter user 'test4'@'localhost' password history default password reuse interval default;

Query OK, 0 rows affected (0.00 sec)

password history default 和password reuse interval default是由password_history 和password_reuse_interval的全局参数决定。


3.2.5 双密码策略(MySQL 8.0 新特性)

MySQL 8.0.14版本中,用户支持双密码(主密码和副密码),双密码策略就是在日常运维中,需要定期更改指定用户密码,同时又需要旧密码暂时保留一定时长的一种策略。其作用是延迟应用与数据库之间的用户新旧密码对接时间。


双密码机制其实就是主密码与备密码,当备密码不再使用时,告知管理员丢弃备密码,此时用户的主密码即是唯一密码,用法如下:


管理员先创建一个新用户 'test1'@'localhost' ,密码是 test1old ,完了更改他的密码为 test1new,并且retain current password。此时 rootnew 即为主密码,而 rootold 即为备密码


mysql> create user 'test1'@'localhost' identified by 'test1old';

Query OK, 0 rows affected (0.01 sec)

mysql> alter user  'test1'@'localhost' identified by 'test1new' retain current password;

Query OK, 0 rows affected (0.01 sec)


接下来用户'test1'@'localhost' 分别使用备密码与主密码连接 MySQL 并且执行一条简单的 SQL 语句:


[root@mysql2 ~]# mysql -utest1 -ptest1new -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

+-------------+

| hello world |

+-------------+

| hello world |

+-------------+

[root@mysql2 ~]# mysql -utest1 -ptest1old -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

+-------------+

| hello world |

+-------------+

| hello world |

+-------------+

可以发现在两个密码都能正常使用,相关业务更改完成后,即可告知管理员丢弃备密码discard old password:


mysql> alter user  'test1'@'localhost' discard old password;

Query OK, 0 rows affected (0.01 sec)

双密码策略有以下需要注意的事项:


1、如果用户本身已经有双密码策略,再次更改新密码时没有带 retain current password 子句,那之前的主密码被替换成新改的密码,但是备密码不会被替换。还有一点需要注意的细节,如果不带 retain current password 子句,并且更改新密码为空串,那么主备密码则会统一更改为空串。下面直接8个空格


mysql> alter user 'test1'@'localhost' identified by '        ';

Query OK, 0 rows affected (0.02 sec)

[root@mysql2 ~]# mysql -utest1 -ptest1old -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 1045 (28000): Access denied for user 'test1'@'localhost' (using password: YES)

2、使用双密码策略时,不能更改用户的认证插件。


mysql> alter user 'test1'@'localhost' identified with sha256_password by 'testtest' retain current password;

ERROR 3894 (HY000): Current password can not be retained for user 'test1'@'localhost' because authentication plugin is being changed.

3、新密码为空,不允许使用备用密码


mysql> alter user  'test1'@'localhost' identified by '' retain current password;

ERROR 3895 (HY000): Current password can not be retained for user 'test1'@'localhost' because new password is empty.


3.2.5 随机密码策略(MySQL 8.0 新特性)

以往旧版本有生成随机密码的需求,在 MySQL 端无法直接设定,MySQL 8.0 直接可以在create user


mysql> create user 'test2'@'localhost' identified by random password;

+-------+-----------+----------------------+-------------+

| user  | host      | generated password   | auth_factor |

+-------+-----------+----------------------+-------------+

| test2 | localhost | 7HcEGYi6:K.*sURH-n.C |           1 |

+-------+-----------+----------------------+-------------+

1 row in set (0.00 sec)


也可以用 set password 子句来设置随机密码


mysql> set password for 'test2'@'localhost' to random;

+-------+-----------+----------------------+-------------+

| user  | host      | generated password   | auth_factor |

+-------+-----------+----------------------+-------------+

| test2 | localhost | tJKznYxoL1u+J3YS

+-------+-----------+----------------------+-------------+

1 row in set (0.00 sec)

也可以用 alter user来设置随机密码


mysql> alter user 'test2'@'localhost' identified by random password;

+-------+-----------+----------------------+-------------+

| user  | host      | generated password   | auth_factor |

+-------+-----------+----------------------+-------------+

| test2 | localhost | vZ-q{OqQqDnaT]gbhCy+ |           1 |

+-------+-----------+----------------------+-------------+

1 row in set (0.00 sec)


3.2.6 失败登录追踪和临时密码锁定(MySQL 8.0 新特性)

失败登录追踪和临时密码锁定,后面我们简称为:FLTTAL 。

和之前几个密码策略不同,FLTTAL 没有全局参数匹配,只能在创建用户或者是更改用户属性时被匹配。 有两个选项

failed_login_attempts 密码错误次数和 password_lock_time 锁定天数


需要注意的是:

1、failed_login_attempts 和 password_lock_time 必须同时不为 0 ,FLTTAL 才能生效。

mysql> create user 'test3'@'localhost' identified by 'test' failed_login_attempts 2 password_lock_time 0;

Query OK, 0 rows affected (0.01 sec)

[root@mysql2 ~]#  mysql -utest3 -ptest11111 -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 1045 (28000): Access denied for user 'test3'@'localhost' (using password: YES)

[root@mysql2 ~]#  mysql -utest3 -ptest11111 -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 1045 (28000): Access denied for user 'test3'@'localhost' (using password: YES)

[root@mysql2 ~]#  mysql -utest3 -ptest11111 -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 1045 (28000): Access denied for user 'test3'@'localhost' (using password: YES)

[root@mysql2 ~]#  mysql -utest3 -ptest -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

+-------------+

| hello world |

+-------------+

| hello world |

+-------------+


2、创建新用户不指定 failed_login_attempts 和 password_lock_time ,则默认关闭 FLTTAL 。

3、已使用FLTTAL的用户,管理员对其 alter user 后可改变原有密码验证策略。


mysql> alter user 'test3'@'localhost' identified by 'test' failed_login_attempts 4 password_lock_time 1;

Query OK, 0 rows affected (0.00 sec)

[root@mysql2 ~]#  mysql -utest3 -ptest11111 -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 1045 (28000): Access denied for user 'test3'@'localhost' (using password: YES)

[root@mysql2 ~]#  mysql -utest3 -ptest11111 -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 1045 (28000): Access denied for user 'test3'@'localhost' (using password: YES)

[root@mysql2 ~]#  mysql -utest3 -ptest11111 -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 1045 (28000): Access denied for user 'test3'@'localhost' (using password: YES)

[root@mysql2 ~]#  mysql -utest3 -ptest11111 -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 3955 (HY000): Access denied for user 'test3'@'localhost'. Account is blocked for 1 day(s) (1 day(s) remaining) due to 4 consecutive failed logins.

4、一旦账户被锁定,即使输入正确密码也无法登录。

[root@mysql2 ~]#  mysql -utest3 -ptest -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 3955 (HY000): Access denied for user 'test3'@'localhost'. Account is blocked for 1 day(s) (1 day(s) remaining) due to 4 consecutive failed logins.

管理员解锁账户方能正常使用:(或者忘记密码,让管理员解锁账号并且重置新密码)

mysql> alter user 'test3'@'localhost' account unlock;

Query OK, 0 rows affected (0.01 sec)

[root@mysql2 ~]#  mysql -utest3 -ptest -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

+-------------+

| hello world |

+-------------+

| hello world |

+-------------+


还有最重要的一点:由于 FLTTAL 对密码验证正确与否的连续性,任意一次成功登录,FLTTAL 计数器重置


[root@mysql2 ~]#  mysql -utest3 -ptest11111 -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 1045 (28000): Access denied for user 'test3'@'localhost' (using password: YES)

[root@mysql2 ~]#  mysql -utest3 -ptest11111 -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 1045 (28000): Access denied for user 'test3'@'localhost' (using password: YES)

[root@mysql2 ~]#  mysql -utest3 -ptest -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

+-------------+

| hello world |

+-------------+

| hello world |

+-------------+

[root@mysql2 ~]#  mysql -utest3 -ptest11111 -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 1045 (28000): Access denied for user 'test3'@'localhost' (using password: YES)

[root@mysql2 ~]#  mysql -utest3 -ptest11111 -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 1045 (28000): Access denied for user 'test3'@'localhost' (using password: YES)

[root@mysql2 ~]#  mysql -utest3 -ptest11111 -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 1045 (28000): Access denied for user 'test3'@'localhost' (using password: YES)

[root@mysql2 ~]#  mysql -utest3 -ptest11111 -e "select 'hello world'" -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

ERROR 3955 (HY000): Access denied for user 'test3'@'localhost'. Account is blocked for 1 day(s) (1 day(s) remaining) due to 4 consecutive failed logins.

[root@mysql2 ~]#


3.3 密码插件

3.3.1 mysql 5.7 版本默认使用的密码插件

mysql_native_password

mysql> show variables like '%authentication%';

+-------------------------------+-----------------------+

| Variable_name                 | Value                 |

+-------------------------------+-----------------------+

| default_authentication_plugin | mysql_native_password |

+-------------------------------+-----------------------+

1 row in set (0.78 sec)

3.3.2 mysql 8.0 版本默认使用的密码插件

caching_sha2_password

mysql> select @@default_authentication_plugin ;

+---------------------------------+

| @@default_authentication_plugin |

+---------------------------------+

| caching_sha2_password           |

+---------------------------------+

1 row in set, 1 warning (0.00 sec)


3.3.3 mysql 8 要兼容之前版本

方法一:alter 修改用户指定密码插件


mysql> alter user 'root'@'localhost' identified with mysql_native_password by '123456';

Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;

Query OK, 0 rows affected (0.01 sec)


方法二:我们可以在my.cnf文件中指定:


[mysqld]

default_authentication_plugin=mysql_native_password


也可以通过命令来实时修改,可以随时生效而且永久生效(MySQL 8.0 推荐使用):


mysql> set persist default_authentication_plugin=mysql_native_password;

Query OK, 0 rows affected (0.00 sec)

3.3.4 MySQL 8.0 多因素身份认证(了解)

MySQL 8.0.27 增加了多因素身份认证功能,可以为一个用户指定多重的身份校验。为此还引入了新的系统变量 authentication_policy ,用于管理多因素身份认证功能。在 MySQL 8.0.27 之前,create user 的时候可以指定一种认证插件,在未明确指定的情况下会取系统变量 default_authentication_plugin的值。default_authentication_plugin 的有效值有3个,分别是 mysql_native_password ,sha256_password ,caching_sha2_password 。


在 MySQL 8.0.27 中由 authentication_policy 来管理用户的身份认证,同时查看下 authentication_policy 和 default_authentication_plugin 的值


mysql> show variables like '%authentication_%';

+-------------------------------+-----------------------+

| Variable_name                 | Value                 |

+-------------------------------+-----------------------+

| authentication_policy         | *,,                   |

| default_authentication_plugin | caching_sha2_password |

+-------------------------------+-----------------------+

2 rows in set (0.06 sec)';


看到 authentication_policy 的默认值是*,,


第1个元素值是*,表示可以是任意插件,默认值取 default_authentication_plugin 的值。如果该元素值不是星号,则必须设置为 mysql_native_password ,sha256_password ,caching_sha2_password 中的一个。


第2,3个元素值为空,这两个位置不能设置成内部存储的插件。如果元素值为空,代表插件是可选的。


我们创建一个用户,不指定插件名称时,自动使用默认插件caching_sha2_password


mysql> create user 'test'@'localhost' identified by'123456';

Query OK, 0 rows affected (0.01 sec)

mysql> select user,host,plugin from mysql.user where user='test';

+------+-----------+-----------------------+

| user | host      | plugin                |

+------+-----------+-----------------------+

| test | localhost | caching_sha2_password |

+------+-----------+-----------------------+

1 row in set (0.00 sec)


指定插件名称时,会使用到对应的插件


mysql> create user 'test4'@'localhost' identified  with mysql_native_password by'123456';

Query OK, 0 rows affected (0.01 sec)


mysql> select user,host,plugin from mysql.user where user='test4';

+-------+-----------+-----------------------+

| user  | host      | plugin                |

+-------+-----------+-----------------------+

| test4 | localhost | mysql_native_password |

+-------+-----------+-----------------------+

1 row in set (0.00 sec)

尝试变更一下 authentication_policy 第一个元素的值,设置为 sha256_password


mysql> set persist authentication_policy='sha256_password,,';

Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'authentication_policy';

+-----------------------+-------+

| Variable_name         | Value |

+-----------------------+-------+

| authentication_policy | *,,   |

+-----------------------+-------+

1 row in set (0.01 sec)

再次创建一个用户,不指定插件的名称


mysql> create user 'test5'@'localhost' identified by'123456';

Query OK, 0 rows affected (0.01 sec)

mysql> select user,host,plugin from mysql.user where user='test5';

+-------+-----------+-----------------+

| user  | host      | plugin          |

+-------+-----------+-----------------+

| test5 | localhost | sha256_password |

+-------+-----------+-----------------+

1 row in set (0.00 sec)


可以看到默认使用的插件是 sha256_password ,说明当 authentication_policy 第一个元素指定插件名称时,default_authentication_plugin 被弃用了


我们现在进行多重身份验证的用户,首先我们恢复 authentication_policy 至默认值


mysql> set persist  authentication_policy='*,,';

Query OK, 0 rows affected (0.01 sec)

mysql> show variables like 'authentication_policy';

+-----------------------+-------+

| Variable_name         | Value |

+-----------------------+-------+

| authentication_policy | *,,   |

+-----------------------+-------+

1 row in set (0.01 sec)


创建一个双重认证的用户,如下创建失败了,因为我们同时用2种内部存储插件。


mysql> create user 'test7'@'localhost' identified by '123456' and identified with mysql_native_password by '123456';

ERROR 4052 (HY000): Invalid plugin "mysql_native_password" specified as 2 factor during "CREATE USER".


那我们来装一个可插拔插件 Socket Peer-Credential


mysql> INSTALL PLUGIN auth_socket SONAME 'auth_socket.so';

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%socket%';

+-------------+---------------+

| PLUGIN_NAME | PLUGIN_STATUS |

+-------------+---------------+

| auth_socket | ACTIVE        |

+-------------+---------------+

1 row in set (0.00 sec)


再创建一个双重认证的用户


mysql> create user 'test7'@'localhost' identified by '123456' and identified with auth_socket as 'root';

Query OK, 0 rows affected (0.05 sec)

mysql> select user,host,plugin,User_attributes from mysql.user where user='test7';

+-------+-----------+-----------------------+----------------------------------------------------------------------------------------------------------------------------------------------+

| user  | host      | plugin                | User_attributes                                                                                                                              |

+-------+-----------+-----------------------+----------------------------------------------------------------------------------------------------------------------------------------------+

| test7 | localhost | caching_sha2_password | {"multi_factor_authentication": [{"plugin": "auth_socket", "passwordless": 0, "authentication_string": "root", "requires_registration": 0}]} |

+-------+-----------+-----------------------+----------------------------------------------------------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)

创建成功,之后用户’test6’@'localhost’必须提供正确的密码,且同时本地主机的登录用户为 root 时,才会验证通过。


[root@mysql2 bin]#mysql -utest7 --password1=123456 --password2  -S /data/mysql/my3307/mysql.sock

mysql: [Warning] Using a password on the command line interface can be insecure.

Enter password:

## 省略部分代码 ##

mysql>


Ok,测试成功。也可以修改同时登陆用户,如下我们先输入一个错误的密码,在输入一个正确的密码


mysql> alter user 'test7'@'localhost' modify 2 factor identified with auth_socket as 'test7';


再次以主机 root 用户身份,提供正确的密码 123 ,登录失败,因此可以认定双重身份认证机制是生效的。



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
27天前
|
存储 关系型数据库 MySQL
MySQL主从复制原理和使用
本文介绍了MySQL主从复制的基本概念、原理及其实现方法,详细讲解了一主两从的架构设计,以及三种常见的复制模式(全同步、异步、半同步)的特点与适用场景。此外,文章还提供了Spring Boot环境下配置主从复制的具体代码示例,包括数据源配置、上下文切换、路由实现及切面编程等内容,帮助读者理解如何在实际项目中实现数据库的读写分离。
MySQL主从复制原理和使用
|
19天前
|
关系型数据库 MySQL Docker
docker环境下mysql镜像启动后权限更改问题的解决
在Docker环境下运行MySQL容器时,权限问题是一个常见的困扰。通过正确设置目录和文件的权限,可以确保MySQL容器顺利启动并正常运行。本文提供了多种解决方案,包括在主机上设置正确的权限、使用Dockerfile和Docker Compose进行配置、在容器启动后手动更改权限以及使用 `init`脚本自动更改权限。根据实际情况选择合适的方法,可以有效解决MySQL容器启动后的权限问题。希望本文对您在Docker环境下运行MySQL容器有所帮助。
33 1
|
1月前
|
缓存 算法 关系型数据库
Mysql(3)—数据库相关概念及工作原理
数据库是一个以某种有组织的方式存储的数据集合。它通常包括一个或多个不同的主题领域或用途的数据表。
56 5
Mysql(3)—数据库相关概念及工作原理
|
21天前
|
SQL NoSQL 关系型数据库
|
1月前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1638 14
|
29天前
|
存储 关系型数据库 MySQL
基于案例分析 MySQL 权限认证中的具体优先原则
【10月更文挑战第26天】本文通过具体案例分析了MySQL权限认证中的优先原则,包括全局权限、数据库级别权限和表级别权限的设置与优先级。全局权限优先于数据库级别权限,后者又优先于表级别权限。在权限冲突时,更严格的权限将被优先执行,确保数据库的安全性与资源合理分配。
|
27天前
|
SQL 关系型数据库 MySQL
Mysql中搭建主从复制原理和配置
主从复制在数据库管理中广泛应用,主要优点包括提高性能、实现高可用性、数据备份及灾难恢复。通过读写分离、从服务器接管、实时备份和地理分布等机制,有效增强系统的稳定性和数据安全性。主从复制涉及I/O线程和SQL线程,前者负责日志传输,后者负责日志应用,确保数据同步。配置过程中需开启二进制日志、设置唯一服务器ID,并创建复制用户,通过CHANGE MASTER TO命令配置从服务器连接主服务器,实现数据同步。实验部分展示了如何在两台CentOS 7服务器上配置MySQL 5.7主从复制,包括关闭防火墙、配置静态IP、设置域名解析、配置主从服务器、启动复制及验证同步效果。
Mysql中搭建主从复制原理和配置
|
1月前
|
SQL 关系型数据库 MySQL
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
尼恩,一位40岁的资深架构师,通过其丰富的经验和深厚的技術功底,为众多读者提供了宝贵的面试指导和技术分享。在他的读者交流群中,许多小伙伴获得了来自一线互联网企业的面试机会,并成功应对了诸如事务ACID特性实现、MVCC等相关面试题。尼恩特别整理了这些常见面试题的系统化解答,形成了《MVCC 学习圣经:一次穿透MYSQL MVCC》PDF文档,旨在帮助大家在面试中展示出扎实的技术功底,提高面试成功率。此外,他还编写了《尼恩Java面试宝典》等资料,涵盖了大量面试题和答案,帮助读者全面提升技术面试的表现。这些资料不仅内容详实,而且持续更新,是求职者备战技术面试的宝贵资源。
阿里面试:MYSQL 事务ACID,底层原理是什么? 具体是如何实现的?
|
1月前
|
存储 SQL 关系型数据库
mysql中主键索引和联合索引的原理与区别
本文详细介绍了MySQL中的主键索引和联合索引原理及其区别。主键索引按主键值排序,叶节点仅存储数据区,而索引页则存储索引和指向数据域的指针。联合索引由多个字段组成,遵循最左前缀原则,可提高查询效率。文章还探讨了索引扫描原理、索引失效情况及设计原则,并对比了InnoDB与MyISAM存储引擎中聚簇索引和非聚簇索引的特点。对于优化MySQL性能具有参考价值。
|
2月前
|
安全 关系型数据库 MySQL
Navicat工具设置MySQL权限的操作指南
通过上述步骤,您可以使用Navicat有效地为MySQL数据库设置和管理用户权限,确保数据库的安全性和高效管理。这个过程简化了数据库权限管理,使其既直观又易于操作。
360 4
下一篇
无影云桌面