mysql 数据库运维
mysql8.0 mysql5.7安装,mysql 创建 赋权用户
mysql8.0用户的创建,赋权
20180628 Chenxin
20190801 Update
说明
本文档除特殊说明处,均为8.0版本默认方式.5.7版本也支持.特殊说明处只针对mysql5.7版本.
卸载系统预装的mysql(否则在初始化数据库的时候无法成功):
yum remove mysql (可能需要执行2次)
which mysql (确保mysql删除完毕)
安装
下载安装包
cd /opt
wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.11-linux-glibc2.12-x86_64.tar.gz #8.0
wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.27-linux-glibc2.12-x86_64.tar.gz #5.7
执行安装
/usr/sbin/groupadd mysql
/usr/sbin/useradd -M -g mysql mysql -s /sbin/nolgin
yum install -y cmake ncurses-devel bison libnuma numactl libaio1 libaio-dev
tar xzvf mysql-8.0.11-linux-glibc2.12-x86_64.tar.gz #根据版本调整
mv mysql-8.0.11-linux-glibc2.12-x86_64 /usr/local/mysql
mkdir /usr/local/mysql/data
chown -R mysql:mysql /usr/local/mysql
修改环境变量
cat >> /etc/profile << EOF
export PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH
EOF
source /etc/profile
配置文件
更改/etc/my.cnf配置文件(注意编码问题)
cat /etc/my.cnf
[client]
port = 3306
socket = /tmp/mysql.sock
default-character-set = utf8mb4
[mysqld]
port = 3306
user = mysql
socket = /tmp/mysql.sock
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
log-error = error.log
关闭bin-log
skip-log-bin
binlog_expire_logs_seconds = 172800 # 5.7版本需要注释掉
增加 为默认值的10倍
innodb_buffer_pool_size=1342177280
使用老版本的密码认证方式,客户端暂时不支持
default-authentication-plugin=mysql_native_password
新加的编码,适用于5.X版本,8.X版本不知道是否适用(部分适用)
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-character-set = utf8mb4 开启会导致msyql8无法启动
大小写敏感,专用coinw
lower_case_table_names=1
最大连接数设置
max_connections=2000
[mysql]
default-character-set = utf8mb4
[mysql.server]
default-character-set = utf8mb4
[mysqld_safe]
default-character-set = utf8mb4
log-error=mysqld.log 同error.log,开启会覆盖msyqld的配置
未采用此方式启动,不会生效.不会覆盖mysqld配置
pid-file=mysqld.pid
初始化
8.0初始化
有密码初始化 #mysqld --defaults-file=/etc/my.cnf --initialize
无密码初始化 #mysqld --defaults-file=/etc/my.cnf --initialize-insecure
这里root用户默认没有密码,执行: mysqld --defaults-file=/etc/my.cnf --initialize-insecure
5.7初始化
有密码初始化 mysqld --initialize --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/
无密码初始化 mysqld --defaults-file=/etc/my.cnf --initialize-insecure
启动mysql
/usr/local/mysql/support-files/mysql.server start
全部搭建完成,启动服务后可以验证一下编码: show variables like '%char%'; #要先初始化才能执行
mysql> show variables like '%char%';
+--------------------------+----------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql/share/charsets/ |
+--------------------------+----------------------------------+
8 rows in set (0.01 sec)
参数说明
1.最大连接数(默认为100)
a.临时方案,重启失效
查看最大连接数 show variables like '%max_connections%';
修改最大连接数 set GLOBAL max_connections = 2000;
b.修改my.cnf
最大连接数设置
max_connections=2000
用户创建与权限配置
登陆
/usr/local/mysql/bin/mysql -u root
use mysql
安全初始化方式后,默认会自动生成一个密码,放到log文件里,比如error.log,格式类似
2019-08-01T07:30:19.871772Z 1 [Note] A temporary password is generated for root@localhost: tlq!*/4fQ
/usr/local/mysql/bin/mysql -u root -P 10306 -p
登陆后,必须先重置密码才能执行其他指令,如下(否则报错,由参数default_password_lifetime导致的):
alter user user() identified by "12345...6";
创建admin用户
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'xxx';
CREATE USER 'admin'@'%' IDENTIFIED BY 'xxx';
赋权admin用户
GRANT ALL PRIVILEGES ON . TO 'admin'@'localhost' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON . TO 'admin'@'%' WITH GRANT OPTION;
配置产品库和对应用户
CREATE DATABASE coinw01;
CREATE USER 'coinw'@'%' IDENTIFIED BY 'xxx';
CREATE USER 'coinw'@'localhost' IDENTIFIED BY 'xxx';
GRANT ALL PRIVILEGES ON coinw01.* TO 'coinw'@'%';
GRANT ALL PRIVILEGES ON coinw01.* TO 'coinw'@localhost;
创建备份账户
CREATE USER 'dumper'@'localhost' IDENTIFIED BY 'cvv......kkfggh[]65.,jk';
GRANT SELECT,LOCK TABLES,EVENT ON . TO 'dumper'@'localhost' WITH GRANT OPTION;
删除多余用户
为安全考虑,mysql的admin建议暂时只启用本地登录;删除mysql中的root和test用户:
use mysql;delete from user where user='';delete from user where user='root'; flush privileges;
查看用户权限
use mysql;
select * from user \G;
清除DB密码记录的日志文件:
echo > /root/.mysql_history
数据文件分盘存储/data分区
/data/mysql_data/data/**.
首先mv /usr/local/mysql/data /data/mysql_data/
再 ln -s /data/mysql_data/data /usr/local/mysql/data
导出表结构/导出整个库
导出表结构(mysqldump -d dbname > xxx.sql),一般几分钟
mysqldump --default-character-set=utf8mb4 -uxbzj -psjErbN29h7heU8sg -P 10306 -d xlogin > xlogin.sql
mysqldump --default-character-set=utf8mb4 -h rm-m5emc856519a6ocibyo.mysql.rds.aliyuncs.com -uroot1 -p -P 3306 -d btc018_vcoin > coinw01.sql
导出整个数据,一般几分钟
遇到报错mysqldump: Got error: 1066: Not unique table/alias: 'avirtualwallettransfer' when using LOCK TABLES,则添加 --single-transaction参数,如下
mysqldump --default-character-set=utf8mb4 --single-transaction -h localhost -uroot1 -p -P 3306 btc018_vcoin > coinw01.sql
另外,若导出非常慢,可以尝试增加参数
mysqldump --default-character-set=utf8mb4 --max_allowed_packet=4194304 --net_buffer_length=16384 -ucoinw -psjE...g -P 10306 btc018_vcoin > ./btc018_vcoin.sql
导入到新建的库中去(时间比较长)
mysql --default-character-set=utf8mb4 -ucoinw -psj....8s..g -P 10306 coinw01 < coinw01.sql # 3.5G数据导入需要2小时
问题:
这里遇到一次连接阿里云RDS异常的情况,原因
1.因为密码里有感叹号,只能手动复制(放在命令行会报错)
2.因为RDS是3306,而本地/etc/my.cnf配置client端口10306(mysql客户端默认连接10306端口).在访问外部3306的RDS时,务必手动指定.如 mysql -h rm-m5...rds.aliyuncs.com -uroot1 -p -P3306 (否则默认连接的会是10306)
mysqldump导出慢的解决方法:
-e 使用包括几个VALUES列表的多行INSERT语法;
--max_allowed_packet=XXX 客户端/服务器之间通信的缓存区的最大大小;
--net_buffer_length=XXX TCP/IP和套接字通信缓冲区大小,创建长度达net_buffer_length的行。
1.先查看目标库的参数值 如下:
mysql> show variables like 'max_allowed_packet';
mysql> show variables like 'net_buffer_length';
2.导出时加上参数: mysqldump --max_allowed_packet=4194304 --net_buffer_length=16384 ... dbname > dbname.sql
备份
备份脚本
[xbzj@ip-10-10-0-200 ~]$ cat rds-bak/sql-xlogin-backup.sh
!/bin/bash
Des: for RDS xlogin backup to S3
20180914 Chenxin
source /etc/profile
cd /bak || mkdir -p /bak
echo "预期整个过程大约会持续10-30分钟"
echo
DB信息
DBuser='xbzj'
DBpasswd='xxxxx'
DBhost='xlogin-read.cyp7d7zwyhrc.us-east-1.rds.amazonaws.com'
DBname='xlogin'
bktime=date +%Y%m%d%H%M%S
删除多日前数据
find ./ -mtime +7 -name "*sql.tar.gz" -exec rm -rf {} ;
filename="$DBname"-"$bktime".sql
执行备份
touch $filename
echo "开始dump数据文件,生成临时sql文件"
mysqldump --column-statistics=0 --opt -R -E --single-transaction --default-character-set=utf8mb4 -h $DBhost -P 10306 -u$DBuser -p$DBpasswd $DBname > $filename
若备份成功,执行压缩和上传至S3
if [ $? == 0 ];then
echo "sql文件dump成功,正在执行压缩sql文件"
tar czvf "$filename".tar.gz $filename --remove-files
echo "压缩完成,正在执行本地文件上传至S3"
/usr/bin/aws s3 sync /bak/ s3://xbzj-data-backup/rds-xlogin-read/ --exclude '' --include 'xlogin-' --acl private --region eu-central-1
fi
mysqldump参数说明:
--column-statistics=0
仅用于mysql8,否则会报一个错误
--opt
等同于--add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, --disable-keys 该选项默认开启, 可以用--skip-opt禁用.
--routines, -R
导出存储过程以及自定义函数。
--events, -E
导出事件。
--single-transaction
保证导出的一致性状态.该选项在导出数据之前提交一个BEGIN SQL语句,BEGIN 不会阻塞任何应用程序且能保证导出时数据库的一致性状态。它只适用于多版本存储引擎(它不显示加锁通过判断版本来对比数据),仅InnoDB。本选项和--lock-tables 选项是互斥的,因为LOCK TABLES 会使任何挂起的事务隐含提交。要想导出大表的话,应结合使用--quick 选项。( --quick, -q 不缓冲查询,直接导出到标准输出。默认为打开状态,使用--skip-quick取消该选项。)
备份策略说明:
将此任务加到预热服的计划任务里,每天1次备份.
加到预热服的Jenkins里作为一个任务,供维护的时候使用.
恢复已备份的库文件
mysql --default-character-set=utf8mb4 -h 192.168.31.129 -P 3306 -uxbzjsqladmin -p..password.. xlogin < ./xlogin-20181030152405.sql
客户端管理工具
MySQL Workbench
mysql官方工具,支持最新的用户加密方式,但安装后,通过新的加密方式(默认)连接的时候会报错,报"发生外部未知错误".重新在服务器上安装mysql,并采用老的加密方式后,就可以连接了.这个工具比较全面,可以查看服务器各状态,用户权限等等.
https://dev.mysql.com/downloads/workbench/
Mysql-front
比较轻量级的mysql-front(不支持mysql8.0的用户新的加密模式),当前版本6.0
http://www.mysqlfront.de/
MySQL 8.0 删除 binlog.0000XX文件 以及 关闭log-bin功能
(注意,仅用于单机版,不能用到主从或集群模式)
参考: https://blog.csdn.net/yunuobing/article/details/74779995
关闭原因(需求):
开启binlog记录功能,会增加从库磁盘I/O等的压力,非必要开启,请关闭。必须开启情况:
1)级联同步A->B->C中间的B时.
2)在从库做数据库备份,数据库备份必须要有全备和binlog日志,才是完整的备份。
关闭流程: 先删除不需要的binlog文件,然后通过配置文件关闭binlog记录功能
1.确认当前状态. 先登录数据库查询log-bin的状态(8.0版本默认是开启的)。
mysql> show variables like 'log_bin';
+---------------+-------+
| log_bin | ON |
+---------------+-------+
2.手动删除binlog
查看当前文件
mysql> show binary logs;
+---------------+------------+
| Log_name | File_size |
+---------------+------------+
| binlog.000031 | 49983 |
| binlog.000032 | 39670 |
| binlog.000033 | 1074115884 |
| binlog.000034 | 1074594937 |
删除1天以前的
mysql> PURGE MASTER LOGS BEFORE DATE_SUB( NOW( ), INTERVAL 1 DAY);
Query OK, 0 rows affected (0.05 sec)
确认删除是否生效
mysql> show binary logs;
+---------------+-----------+
| Log_name | File_size |
+---------------+-----------+
| binlog.000086 | 802811016 |
| binlog.000087 | 155 |
+---------------+-----------+
2 rows in set (0.00 sec)
删除指定某个文件之前的所有日志
mysql> PURGE MASTER LOGS TO 'binlog.000087';
Query OK, 0 rows affected (0.19 sec)
确认删除是否生效
mysql> show binary logs;
+---------------+-----------+
| Log_name | File_size |
+---------------+-----------+
| binlog.000087 | 155 |
+---------------+-----------+
1 row in set (0.00 sec)
3.修改配置文件
编辑my.cnf文件,一般路径为:/etc/my.cnf
在mysqld下面添加:skip-log-bin 或者disable-log-bin(未测试)
4.重启Mysql.
/usr/local/mysql/support-files/mysql.server restart
5.确认状态修改是否成功
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | OFF |
+---------------+-------+
1 row in set (0.00 sec)
再次查看binlog,则会报错(因为关闭了):
mysql> show binary logs;
ERROR 1381 (HY000): You are not using binary logging
mysql> show variables like 'expire_log%';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| expire_logs_days | 0 |
+------------------+-------+
1 row in set (0.00 sec)
mysql> show variables like 'binlog_expire_logs_seconds';
+----------------------------+--------+
| Variable_name | Value |
+----------------------------+--------+
| binlog_expire_logs_seconds | 172800 |
+----------------------------+--------+
1 row in set (0.00 sec)
附,对应的my.cnf配置文件:
[root@localhost data]# cat /etc/my.cnf
[client]
port = 3306
socket = /tmp/mysql.sock
default-character-set = utf8mb4
[mysqld]
port = 3306
user = mysql
socket = /tmp/mysql.sock
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
log-error = error.log
关闭bin-log
skip-log-bin
关闭后,过期时间就无所谓了
binlog_expire_logs_seconds = 172800
使用老版本的密码认证方式,客户端暂时不支持
default-authentication-plugin=mysql_native_password
新加的编码,适用于5.X版本,8.X版本不知道是否适用
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-character-set = utf8mb4 开启会导致msyql8无法启动
[mysql]
default-character-set = utf8mb4
[mysql.server]
default-character-set = utf8mb4
[mysqld_safe]
default-character-set = utf8mb4
log-error=mysqld.log 同error.log
pid-file=mysqld.pid
扩展知识
mysql8.0用户的创建,赋权
20180628 Chenxin
mysql8在创建用户赋权跟以前的版本有所不同.
配置老的加密方式-配置文件my.cnf
因目前mysql8最新的用户验证方式,很多客户端不支持,且目前来看,不是很推荐(貌似乱码).修改回老的认证方式的话,my.cnf文件配置:
default-authentication-plugin=mysql_native_password
创建用户与赋权用户
create user '用户'@'主机' identified by '密码';
grant 权限 on 数据库 to '用户'@'主机'
会报错的写法:(过去都是这种写法-无需create)
GRANT ALL PRIVILEGES ON . TO 'admin'@'localhost' IDENTIFIED BY 'xxx';
报错信息:Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IDENTIFIED BY 'xxx” at line 1
正确的写法:
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'xxx';
GRANT ALL PRIVILEGES ON . TO 'admin'@'localhost';
不推荐:GRANT ALL PRIVILEGES ON . TO 'admin'@'localhost' WITH GRANT OPTION;
可见,在授权的语句中需要去掉 IDENTIFIED BY 'password';其中,关键字 “privileges” 可以省略.
WITH GRANT OPTION说明
让授权的用户可以将这些权限 grant 给其他用户.这个特性一般用不到.实际中,数据库权限最好由 DBA 来统一管理.
grant, revoke 用户权限后,该用户只有重新连接 MySQL 数据库,权限才能生效.
grant 增删改查.
grant insert,delete,update,select on testdb.* to common_user@'%'
grant 作用在整个 MySQL 服务器上:
grant all on . to dba@localhost; — dba 可以管理 MySQL 中的所有数据库
grant 作用在存储过程.函数上:
grant execute on procedure testdb.pr_add to ‘dba'@'localhost'
grant execute on function testdb.fn_add to ‘dba'@'localhost'
单独授予某种权限的写法:
GRANT SELECT ON db.table TO 'test'@'localhost';
更新用户密码
mysql-8
ALTER USER 'admin'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
说明:(上一个版本使用以下)
mysql-5
use mysql
update user set password=password('as..password...2') where user='mysqladmin' and host='%';
flush privileges;
查看用户权限(几种方式)
select host, user, authentication_string, plugin from user;
SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM mysql.user;
select * from user \G; (如果采用新加密方式,输出非常容易乱码,造成控制台异常.不知道对数据是否有影响.之后重装了)
查看某个用户对哪些库拥有权限
show grants for 'xbzjsqladmin'@'localhost';
显示:GRANT USAGE ON . TO xbzjsqladmin
@localhost
#这里USAGE是无权限的意思
对于GRANT USAGE ON:
mysql> GRANT USAGE ON . TO 'name'@'localhost';
一个账户有用户名name,没有密码.该账户只用于从本机连接.未授予权限.通过GRANT语句中的USAGE权限,你可以创建账户而不授予任何权限.它可以将所有全局权限设为'N'.假定你将在以后将具体权限授予该账户.
查看当前用户权限
show grants;
收回权限
revoke 跟 grant 的语法差不多,只需要把关键字 “to” 换成 “from” 即可:
revoke all on . from 'admin'@'%';
REVOKE只能取消用户权限,而不能删除用户.
即使取消了所有的权限,用户仍然可以连接到服务器.
要想彻底的删除用户,必须使用DELETE语句将该用户的记录从MySQL数据库中的user表中删除.
该语句的语法格式如下:
Delete from user where user = "user_name" and host = "host_name" ;
再比如:
delete from user where user='';
delete from user where user='root';
flush privileges;
刷新权限-所有操作后,应执行
flush privileges;
备注1
grant经常给开发人员的权限
创建表.索引.视图.存储过程.函数等权限.
grant 创建.修改.删除 MySQL 数据表结构权限.
grant create on testdb.* to developer@'192.168.0.%';
grant alter on testdb.* to developer@'192.168.0.%';
grant drop on testdb.* to developer@'192.168.0.%';
grant 操作 MySQL 外键权限.
grant references on testdb.* to developer@'192.168.0.%';
grant 操作 MySQL 临时表权限.
grant create temporary tables on testdb.* to developer@'192.168.0.%';
grant 操作 MySQL 索引权限.
grant index on testdb.* to developer@'192.168.0.%';
grant 操作 MySQL 视图.查看视图源代码 权限.
grant create view on testdb.* to developer@'192.168.0.%';
grant show view on testdb.* to developer@'192.168.0.%';
grant 操作 MySQL 存储过程.函数 权限.
grant create routine on testdb.* to developer@'192.168.0.%';
grant alter routine on testdb.* to developer@'192.168.0.%';
grant execute on testdb.* to developer@'192.168.0.%';
备注2
mysql授权表共有5个表
user表
列出可以连接服务器的用户及其口令,并且它指定他们有哪种全局(超级用户)权限.
在user表启用的任何权限均是全局权限,并适用于所有数据库.
例如,如果你启用了DELETE权限,在这里列出的用户可以从任何表中删除记录,所以在你这样做之前要认真考虑.
db表
db表列出数据库,而用户有权限访问它们.在这里指定的权限适用于一个数据库中的所有表.
host表
host表与db表结合使用在一个较好层次上控制特定主机对数据库的访问权限,这可能比单独使用db好些.
这个表不受GRANT和REVOKE语句的影响,所以,你可能发觉你根本不是用它.
tables_priv表
tables_priv表指定表级权限,在这里指定的一个权限适用于一个表的所有列.
columns_priv表
columns_priv表指定列级权限.这里指定的权限适用于一个表的特定列.
扩展知识2-msyql的启动方式与匹配的配置文件
一、MySQL读取配置文件的顺序
读取顺序:/etc/my.cnf > /etc/mysql/my.cnf > /usr/etc/my.cnf > ~/.my.cnf
命令验证:
[root@mysql ~]# mysql --verbose --help | grep my.cnf
order of preference, my.cnf, $MYSQL_TCP_PORT,/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf
二、MySQL启动方式
MySQL的启动方式通常分成三种:mysqld、mysqld_safe、mysqld_multi(主要用于多实例启动)
三种方式的关系:
首先当我们使用service mysqld start或者/etc/init.d/mysqld start这样的方式启动的时候,其实是使用了mysql.server这个脚本,这个脚本默认会调用mysqld_safe来启动mysqld,所以通常我们启动mysql之后查看进程的时候会发现有mysqld和mysqld_safe这两个进程存在。这两种通常都是单实例的启动方式,当然也可以使用mysqld来启动多实例的。而mysqld_multi用来启动多实例,也是通过先调用mysqld_safe和mysqld来启动mysql的。
三、MySQL启动原理
默认的mysql的服务启动程序是mysql.server,mysql.server程序主要是会用到两个程序和一个函数,分别是my_print_defaults、myslqd_safe和parse_server_arguments
1、my_print_defaults:读取my.cnf配置文件,输出参数传递给parse_server_arguments,该程序只读my.cnf中[mysqld]中的参数。
2、parse_server_arguments:该函数处理my_print_defaults传递过来的参数赋值给--basedir、--datadir、--pid-file、--server-startup-timeout
3、myslqd_safe:mysqld_safe程序调用mysqld程序来启动mysql服务,[mysqld_safe]会覆盖mysqld部分中的参数
4、mysqld_multi会读取配置文件中的[mysqld_muti],[mysqldN]下面的参数,N需要时一个整数,建议用端口号表示,该部分的配置会覆盖[mysqld]部分中的配置
5、在mysqld进程挂掉的时候,mysqld_safe进程会监测到并重新将mysqld启动起来。