MySQL8.0日常管理

## 3.1 启动与关闭方式 ### 1.常规启动和关闭方式 ``` systemd: systemctl {stop|start|restart} mysqld sys-v: service mysqld {stop|start|restart}==/etc/init.d/mysqld start # 注意:{stop|start|restart}括号内3选1,分别为停止、启动和重启。 # 采用二进制安装,上述命令的启动脚本来自/usr/local/mysql/support-files/mysql.server # 注意:上述命令本质: # 停止原理:kill mysql_pid # 启动原理:mysqld_safe .... ``` ### 2.维护启动和关闭方式 a.维护性启动方式(往往需要额外加参数启动) ``` # --mysqlx=0为关闭33060端口,这是8.0增加的功能。 mysqld --port=3306 --mysqlx=0 & # root管理员密码丢失使用这个命令启动。 mysqld_safe --skip-grant-tables --skip-networking & # 使用mysqld和mysqld_safe启动优势:可以额外加参数启动,命令行高于配置文件my.cnf里的配置。 ``` b.维护性关闭方式 ``` kill pid #<==这里的pid为数据库服务对应的进程号。 killall mysqld #<==这里的mysqld是数据库服务对应的进程名字。 pkill mysqld #<==这里的mysqld是数据库服务对应的进程名字。 # 注意:千万不要用-9,强制杀死。 ``` ### 3. 其它关闭方式 MySQL提供了一个mysqladmin管理命令,可以用来优雅的关闭数据库,命令如下: ``` [root@oldboy ~]# mysqladmin shutdown #<==注意密码要正确。 #还可以登录到数据库里面执行关闭。 mysql> shutdown; mysql> restart; ``` --- ## 3.2 MySQL启动与关闭原理 ### 3.2.1 关闭原理 systemctl命令关闭原理分析 ``` [root@oldboy ~]# sed -n '281,301p' /etc/init.d/mysqld 'stop') # Stop daemon. We use a signal here to avoid having to know the # root password. if test -s "$mysqld_pid_file_path" then # signal mysqld_safe that it needs to stop touch "$mysqld_pid_file_path.shutdown" mysqld_pid=`cat "$mysqld_pid_file_path"` if (kill -0 $mysqld_pid 2>/dev/null) ###判断pid对应的进程是否运行. then echo $echo_n "Shutting down MySQL" kill $mysqld_pid #=======================kill pid # mysqld should remove the pid file when it exits, so wait for it. wait_for_pid removed "$mysqld_pid" "$mysqld_pid_file_path"; return_value=$? else log_failure_msg "MySQL server process #$mysqld_pid is not running!" rm "$mysqld_pid_file_path" fi ``` ### 3.2.2 启动原理 采用systemctl或者service方式关闭数据库的本质都是调用mysqld_safe命令启动。对应脚本如下: ``` [root@oldboy ~]# sed -n '255,279p' /etc/init.d/mysqld 'start') #<==启动命令的传参。 cd $basedir echo $echo_n "Starting MySQL" if test -x $bindir/mysqld_safe then # Give extra arguments to mysqld with the my.cnf file. This script # may be overwritten at next upgrade. $bindir/mysqld_safe --datadir="$datadir" --pidfile="$mysqld_pid_file_path" $other_args >/dev/null & #<==这正是在初始化数据库时系统给出的快速启动MySQL方式。 ...省略若干行... ;; # 结论: # systemctcl关闭数据库原理 kill pid # systemctcl启动数据库原理 mysqld_safe [root@oldboy ~]# ps -ef|grep mysql|grep -v grep root 21671 1 0 23:06 ? 00:00:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data/3306/data --pidfile=/data/3306/data/oldboy.pid mysql 21827 21671 27 23:06 ? 00:00:01 /usr/local/mysql/bin/mysqld -- basedir=/usr/local/mysql --datadir=/data/3306/data --plugindir=/usr/local/mysql/lib/plugin --user=mysql --log-error=oldboy.err --pidfile=/data/3306/data/oldboy.pid --socket=/tmp/mysql.sock --port=3306 ``` #/etc/init.d/mysqld是MySQL自带的使用Shell编写的启动脚本,执行脚本后最终会调用mysqld_safe命令脚本,mysqld_safe脚本执行后又会调用mysqld主程序启动MySQL服务,因此在前文查看MySQL进程时,会发现不仅有mysqld_safe进程,还有mysqld进程。 ``` #生产注意:一定不要随意重启数据库,会影响业务. # 1.20秒业务不可用。 # 2.业务访问可能变慢(缓存失效)。 ``` ### 3.2.3 退出MySQL 数据库维护完毕后,如果需要退出,则可以执行下面的命令: ``` 1、quit (\q) Quit mysql。 2、exit (\q) Exit mysql. Same as quit。 3、快捷键Ctrl+d。 ``` ### 3.2.4 登录MySQL ``` # mysql命令选项: -u用户 -p密码 -Ssocket #多实例 -P端口 -h主机 #远程登录 -e 非交互操作mysql # mysql登录示例: [root@oldboy ~]# mysql -uroot -p -S /tmp/mysql.sock -P3306 -hlocalhost -e "show databases;" Enter password: +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ ``` 3.5 MySQL命令行帮助 ``` #?和help ====>Linux下man # 核心: help contents # 创建数据库: # 帮助方法1:命令行查帮助 # 步骤1.help contents mysql> help contents You asked for help about help category: "Contents" For more information, type 'help <item>', where <item> is one of the following categories: Data Definition # 步骤2.? Data Definition mysql> ? Data Definition ALTER DATABASE ALTER EVENT ALTER FUNCTION ALTER TABLESPACE ALTER VIEW CREATE DATABASE # 步骤3.mysql> ? CREATE DATABASE # 创建数据库语法就看到了 mysql> ? CREATE DATABASE CREATE DATABASE Syntax: CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name 说明: 1){DATABASE | SCHEMA} 必须2选1. 2)[IF NOT EXISTS]中括号可选. create_option: [DEFAULT] { CHARACTER SET [=] charset_name | COLLATE [=] collation_name | ENCRYPTION [=] {'Y' | 'N'} } # 步骤4:创建 CREATE DATABASE db_name # 帮助方法2:官方文档 URL: https://dev.mysql.com/doc/refman/8.0/en/create-database.html # 帮助方法3.baidu https://dev.mysql.com/doc/refman/8.0/en/drop-table.html # 帮助方法4:问会的人 ``` ---- ## 3.3 管理MySQL用户 ### 3.3.2 MySQL用户 1.用户组成 用户@主机域,两部分共同构成了mysql用户,主机域是登录的客户端主机的IP范围。 2.用户特点 ``` oldboy@'localhost' #<==本机用户,只能在本机登录。 适合单机. oldboy@'10.0.0.2' #<==单一IP,只能从10.0.0.2这台机器登录 oldboy@'10.0.0.%' #<==模糊匹配,一个范围内IP,例如10.0.0.1-10.0.0.254。 集群模式. oldboy@'10.0.0.1%' #<==模糊匹配,一个范围内的IP,例如10.0.0.10-10.0.0.19/10.0.0.100- 10.0.0.199 oldboy@'10.0.0.0/255.255.0.0' #<==一个子网内的所有IP。 oldboy@'%' #<==模糊匹配,任意用户都可以登录IP,此方式极不可取。 #在前一章节,安装数据库后,输入mysql直接登录到数据库中,实际的用户为:root@localhost; ``` **MySQL用户安全规范**(生产技巧) ``` a. 主机域范围要尽量的小,最好细化到单一IP,甚至是用locahost,%模糊匹配应坚决禁止。 b. 用户名应有实际意义,一看就明白什么项目,比如:blog。 c. 无用的用户应删除或者锁定。 d. 密码应该至少为数字、大小写字母、特殊字符三种以上复杂度,非字典密码,且总数8位以上。 e. 应为一个项目设置一个对应用户,禁止使用root用户作为业务项目的用户。 ``` 3.查询用户 管理库mysql,用户表user。 ``` # 1)查看当前登录用户 mysql> select user(); +----------------+ | user() | +----------------+ | root@localhost | +----------------+ # 2)查看用户表的表结构 mysql> desc mysql.user; ========================== mysql> use mysql mysql> desc user; # 3)查询用户 mysql> select user,host from mysql.user; +------------------+-----------+ | user | host | +------------------+-----------+ | mysql.infoschema | localhost | | mysql.session | localhost | | mysql.sys | localhost | | root | localhost | ====>当前登录 +------------------+-----------+ # 查询更多列 mysql> select user,host,authentication_string,plugin from mysql.user; ``` 4.增加用户 分别创建oldboy、oldgirl用户,允许从10.0.0.0/24整个网段的主机访问数据库, ``` create user oldboy@'10.0.0.%' identified by '123'; create user oldgirl@'10.0.0.%' identified with mysql_native_password by '123'; #推荐使用。 ``` **重点知识:*** ``` 1.8.0之后必须先建用户后授权,grant命令不再支持建用户同时创建密码功能。 2.8.0之前密码插件使用的mysql_native_password,8.0之后使用是caching_sha2_password。 # 这可能导致使用老的客户端程序(例如sqlyog客户端)无法连接新的8.0版本数据库。 解决方法: a. 增加用户时,指定mysql_native_password插件进行密码加密。 b. 修改用户时,可以修改指定的插件。 c. 配置文件my.cnf中可以指定默认加密插件为mysql_native_password。 ``` 5.修改用户 1)将oldboy用户的密码插件更改为mysql_native_password。 `mysql>alter user oldboy@'10.0.0.%' identified with mysql_native_password by '123';` 6.锁定用户 2)锁定和解锁用户(不确定是否有用的账户,可以先锁定) ``` mysql> alter user oldgirl@'10.0.0.%' ACCOUNT LOCK; mysql> alter user oldgirl@'10.0.0.%' ACCOUNT UNLOCK; ``` 7.删除用户 `mysql> drop user oldgirl@'10.0.0.0/255.255.255.0';` ### 3.3.3 MySQL客户端 1.客户端介绍 1) 开发人员常用:navicat/sqlyog/phpmyadmin 2) 运维人员常用:mysql 2.创建远程连接管理员 ``` mysql> create user oldboy@'10.0.0.%' identified with mysql_native_password by 'oldboy123'; mysql> grant all on *.* to oldboy@'10.0.0.%' with grant option; mysql> flush privileges; ``` --- ## 3.4 管理MySQL用户密码 ### 3.4.1 设置管理员root密码 ``` mysqladmin password 'oldboy123' # 登录测试 mysql -uroot -poldboy123 ``` ### 3.4.2 修改管理员root密码 1.Linux命令行修改法 ``` #<== oldboy123为原密码,新密码为oldboy。 mysqladmin -uroot -poldboy123 password 'oldboy' mysql -uroot -poldboy ``` 2.SQL语句修改法 ``` #常用于root密码遗忘后使用 mysql> alter user root@'localhost' identified by 'oldboy123'; mysql> flush privileges; #<==刷新权限使得修改密码生效。 #交互登录 mysql -uroot -p ``` ### 3.4.3 找回MySQL root用户密码 ``` 1.首先停止MySQL服务。 systemctl stop mysqld netstat -lntup|grep 330 2.启动mysql服务。 mysqld_safe --skip-grant-tables --skip-networking & ###--skip-grant-tables(忽略授权登录验证)和--skip-networking(忽略网络) 3.无需密码登录MySQL。 mysql 4.修改root密码为新密码。 mysql> flush privileges; #<==此命令必须先执行。 mysql> alter user root@'localhost' identified by 'oldboy123'; mysql> quit 5.重启mysql killall mysqld systemctl start mysqld netstat -lntup|grep 330 6.登录验证 mysql -uroot -p ``` **遇到的故障:** ``` mysql> select user,host from mysql.user; +------------------+-----------+ | user | host | +------------------+-----------+ | oldboy | 10.0.0.% | | oldgirl | 10.0.0.% | | mysql.infoschema | localhost | | mysql.session | localhost | | mysql.sys | localhost | | root | localhost | +------------------+-----------+ 6 rows in set (0.01 sec) mysql> quit Bye [root@db01 ~]# mysql -uoldboy -p123; ERROR 1045 (28000): Access denied for user 'oldboy'@'localhost' (using password: YES) # 以上是使用oldboy@localhost登录 mysql -uoldboy -p123 -hlocalhost #而实际用户是:oldboy@10.0.0.%,所以无法登录 #正确登录 mysql -uoldboy -p123 -h10.0.0.51 ``` ## 3.5 管理MySQL用户权限 ### 3.5.1 什么是MySQL权限 MySQL权限是针对用户设置的,用来控制及约束用户对数据库里不同对象(库、表)都能干啥,比如增加的权限,删除的权限,修改的权限、查看的权限等。 ### 3.5.2 MySQL权限 1.查看权限 `mysql> show privileges;` 2.ALL PRIVILEGES权限说明 ALL PRIVILEGES(也可省略为ALL),包含除了grant option以外的所有权限。 另外,工作中授权时,授权用户应尽量授权最小的满足业务需求的权限,而不是直接授权“ALL”。 grant option ===>可以创建真正管理员用户的权限) Grant option To give to other users those privileges you possess 创建一个和root管理员一样的权限: mysql创建和root等同的权限: ``` create user oldboy@'localhost' identified by '123'; grant all on . to oldboy@'localhost' with grant option; flush privilges; ``` 3.几个案例 案例1:创建test用户,具备所有库表权限,从localhost主机登录管理数据库,密码是test123。 ``` # 方法1:MySQL5.7以前,grant命令可以授权的同时,创建用户并设置好密码,命令如下: mysql> grant all on *.* to 'test'@'localhost' identified by 'test123'; mysql> flush privileges; # 方法2:但是5.7及以后必须单独创建用户,再进行授权,不能用grant命令一步到位了,实际命令为: mysql> create user 'test'@'localhost' identified with mysql_native_password by 'test123'; mysql> grant all privileges on *.* to 'test'@'localhost'; mysql> flush privileges; ``` 案例2:创建blog用户,具备oldboy库里表增和查的权限,登录网段为10.0.0.0/24,密码是123。 ``` create user blog@'10.0.0.0/24' identified by '123'; grant insert,select on oldboy.* to blog@'10.0.0.0/24'; ``` 案例3:创建用户,具备mysql库里user表的增和查权限,登录网段为10.0.0.0/24,密码是123。 ``` create user zhangsan@'10.0.0.0/24' identified by '123'; grant insert,select on mysql.user to zhangsan@'10.0.0.0/24'; ``` ### 3.5.3 查看用户权限 1.专门查看用户授权命令 `mysql> show grants for 'oldboy'@'localhost';` 2.授权表说明(了解) 1)说明(专业DBA需要会) ``` *.* #<==授权[所有库.所有表],查mysql.user oldboy.* #<==单库范围,oldboy库里的所有表,查mysql.db oldboy.t1 #<==单表范围,oldboy库里的t1表。查mysql.tables_priv ``` 2)实践: ``` #所有库所有表查mysql.user mysql> select * from mysql.user where user='oldboy' and host='10.0.0.%'\G #库级别:查mysql.db mysql> select * from mysql.db where user='blog'\G #表级别查mysql.tables_priv mysql> select * from mysql.tables_priv where user='zhangsan ``` ### 3.5.4 企业中grant授权权限说明 1)连接数据库的对象 Web服务(php,tomcat,python)/app服务 2)如何授权? select,insert,update 针对表内容授权. 合理授权: `grant select,insert,update,delete on oldboy.* to test@'172.16.1.%';` 除了select,insert,update,delete 权限外的权限,用户用不到的:DBA的权限,create,drop 都应该控制在DBA人员手里.给别人最小的权限,拥有最大的安全. 3)安装wordpess,要网上用,用户如何授权合理? 1.安装时候授权: `select,insert,update,delete,create,drop` 2.安装回收create,drop,剩余 `select,insert,update,delete` 注意:授予用户权限时有如下3条安全红线不要轻易跨过。 ``` a.权限一定不用all, 而是select、insert. update、 delete权限。 b.库表不用,而应用oldboy.*格式具体到库更为妥当。 c.主机域不用%,而应用内网的IP段,即'172.16.1.%'格式。 ``` 结论:只要是应用服务器用户授权,99.99%,select,insert,update,delete 对于表\库对象的修改一定是管理员操作,不能交给开发管 ### 3.5.4 撤销授权权限 1.语法: ``` REVOKE INSERT ON . FROM 'jeffrey'@'localhost'; REVOKE 'role1', 'role2' FROM 'user1'@'localhost', 'user2'@'localhost'; REVOKE SELECT ON world.* FROM 'role3'; ``` 2.举例: 安装wordpress如何授权合理? 1.安装时候授权: ``` select,insert,update,delete,create,drop create user blog@'localhost' identified by '123'; grant select,insert,update,delete,create,drop on wordpress.* to blog@'localhost'; show grants for blog@'localhost'; ``` 2.安装回收create,drop,剩余 ``` select,insert,update,delete REVOKE create,drop ON wordpress.* FROM blog@'localhost'; ``` 注意: ###回收和授权命令的库表,用户,要严格对应否则收不回来。 ###关键字不区分大小写,但是库\表名小写,而且字母开头.只能含有字母数字下划线. --- ## 3.6 MySQL连接管理 ### 3.6.1 客户端连接MySQL服务原理 MySQL是一个典型的C/S服务结构软件 C/S:client/server/胖客户端: C:client:mysql、mysqladmin、mysqldump、mysqlbinlog等 S:mysqld B/S #瘦客户端,趋势 B/S Browser/Server 浏览器/服务器 ### 3.6.2 MySQL连接方式 1.TCP/IP和Socket连接介绍及实践 **Socket连接:本机** `mysql -uroot -poldboy123 -S /tmp/mysql.sock` **TCP/IP:** 客户端软件:例如sqlyog(开发人员) mysql -uroot -poldboy123 -h10.0.0.51 ### 3.6.3 MySQL连接提示符说明 ``` mysql> prompt \u@oldboy \r:\m:\s-> root@oldboy 04:53:18-> ``` 配置文件:/etc/my.cnf 无需重启 ``` [client] prompt=\\u@oldboy \\r:\\m:\\s-> ``` --- ## 3.7 MySQL配置文件及参数 ### 3.7.1 配置文件 默认首个配置位置:/etc/my.cnf ``` [root@oldboy ~]# mysqld --help --verbose|grep my.cnf /etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf ``` ### 3.7.2 参数配置方式 1.源码包编译安装时 2.系统命令行指定部分MySQL参数 1)例:服务端:忽略授权表启动mysql的命令: `mysqld_safe --skip-grant-tables --skip-networking & ` 2)例:客户端:登录mysql `mysql -uroot -poldboy123 -h 10.0.0.128 -P3306` 3.MySQL命令行临时设置MySQL参数 查看所有参数`show variables;` 修改参数:两个级别,全局:global,局部:session ### 3.7.3 参数查看 1.1 global级:全局 ``` mysql> select @@global.wait_timeout; or mysql> show global variables like 'wait_timeout'; or mysql> select * from performance_schema.global_variables where variable_name='wait_timeout'; ``` 1.2 session级:局部 ``` mysql> select @@wait_timeout; or mysql> select @@session.wait_timeout; or mysql> show variables like 'wait_timeout'; or mysql> show session variables like 'wait_timeout'; or mysql> select * from performance_schema.session_variables where variable_name ='wait_timeout'; ``` ### 3.7.4 参数修改 2.1 session级参数的修改 ``` mysql> set wait_timeout=10; or mysql> set session wait_timeout=10; ``` 2.2 global级参数的修改 `mysql> set global wait_timeout=10;` # 不能重启MySQL,还要需要参数,用这个命令。 2.3 配置文件修改:重启生效 ``` vi /etc/my.cnf [mysqld] wait_timeout = 10 ``` 工作中不允许重启MySQL,改参数用下面方法 1.先set global全局修改。 2.同时改配置文件/etc/my.cnf。 ### 3.7.5 my.cnf配置 1.默认首个配置位置:/etc/my.cnf ``` [root@oldboy ~]# mysqld --help --verbose|grep my.cnf [/etc/my.cnf] /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf ``` 2.mysql配置文件基本结构 执行cat /etc/my.cnf查看前文安装时的简易my.cnf配置文件。 ``` [root@oldboy ~]# cat /etc/my.cnf #by oldboy weixin:oldboy0102 [mysqld] #<==服务端标签,需要重启,影响服务运行。 user=mysql basedir=/usr/local/mysql datadir=/data/3306/data port=3306 socket=/tmp/mysql.sock [client] #<==mysql客户端标签 socket=/tmp/mysql.sock [mysqld_safe] #<==启动标签 [mysqldump] #<==备份标签 ``` 客户端标签只影响本机指定客户端程序的运行,配置后直接生效。