1、 数据库基础知识介绍
1. DBA是什么
DBA(数据库管理员),认证英文是Database Administrator
2. DBA职业规划
2.1 需要学习的内容
(1)MySQL 5.7 安装部署(二进制)***** 编译自己扩展
(2)MySQL升级步骤扩展 ***
(3)MySQL5.7 体系结构原理 *****
(4)MySQL基础管理 *****
(5)基础SQL语句使用 *****
(6)SQL高级应用 ***
(7)Information_schema获取元数据 ***
(8)索引、执行计划管理(基础优化)*****
(9)存储引擎 *****
(10)日志管理 *****
(11)备份与恢复 ******
(12)主从复制及架构演变 ******
(13)传统的高可用及读写分离(MHA&Atlas)****
(14)传统分布式架构设计与实现-扩展(Mycat--->DBLE,DRDS)**
(15)MySQL 5.7 高可用及分布式架构-扩展(MGR,InnoDB Cluster)***
(16)MySQL优化(安全、性能) ****
(17)MySQL 监控(zabbix、Open-falcon) ****
(18)RDS(阿里云课程) *****
额外要会的:
Redis
mongodb
了解:
PG
Oracle
3. DBA职业素养
3.1 人品
责任----权利---态度
3.2 操作严谨
操作数据库修改、删除类的命令时,再三考虑,而且要有理论与实践的支撑
3.3 细心
把最简单的事情做的最漂亮、最专业
3.4 心态
别惹事,出事别怕事
4. DBA职业技能
4.1 熟悉操作系统(精通)
4.2 熟悉公司业务
产品功能
用户行为(热数据、热功能)
4.3 熟悉行业
熟悉行业发展趋势
数据库版本
数据库产品类型
(数据库排行网站https://db-engines.com/en/ranking)
建议多参加一些数据库的会议
5. 数据库产品
5.1 什么是数据?
图片、文档、账号密码、音视频等
5.2 DBMS 数据库管理系统
RDBMS(关系型数据库,Relational Database Management System):Oracle、MySQL、PG、MSSQL
NoSQL(非关系型数据库):MongoDB、Redis、ES
NEWSQL(分布式型数据库):TiDB、Spanner、AliSQL、OB、PolarDB(阿里自己研发的数据库)
5.3. MySQL 企业版本选择,GA版
每年发布4个大版本,一个季度发布一次,每个小版本发布时隔大概3个月左右
5.6(大版本):5.6.34、5.6.36、5.6.38(2017913)、5.6.40(小版本)
5.7(大版本):5.7.18、5.7.20(2017913)、5.7.24(小版本)
8.0(大版本):8014、8015、8016(小版本)
5.4 关于数据库版本面试
你在公司干了几年?你们公司用的什么版本的MySQL?
查询MySQLGA时间(www.mysql.com)
2、MySQL安装
1. MySQL 5.7.26二进制版本安装
[root@db01 /server/tools]# tar zxf mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz
[root@db01 /server/tools]# ls
mysql-5.7.26-linux-glibc2.12-x86_64 mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz
[root@db01 /server/tools]# mkdir -p /application/
[root@db01 /server/tools]# ls
mysql-5.7.26-linux-glibc2.12-x86_64 mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz
[root@db01 /server/tools]# mv mysql-5.7.26-linux-glibc2.12-x86_64 /application/mysql
[root@db01 /server/tools]# cd /application/
[root@db01 /application]# ls
mysql
1.1 创建用户并处理原始环境
[root@db01 /application]# yum -y remove mariadb*
[root@db01 /application]# rpm -qa mariadb
[root@db01 /application]#
[root@db01 /application]# useradd mysql -M -s /sbin/nologin -u 1111
1.2 设置环境变量
[root@db01 /application]# echo "export PATH=/application/mysql/bin:$PATH" >> /etc/profile
[root@db01 /application]# source /etc/profile
[root@db01 /application]# tail -1 /etc/profile
export PATH=/application/mysql/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@db01 /application]# mysql -V
mysql Ver 14.14 Distrib 5.7.26, for linux-glibc2.12 (x86_64) using EditLine wrapper
1.3 创建数据目录并授权
注意:生产环境中,数据目录必须另存一块盘
1. 这里选择在虚拟机中添加一块新的磁盘,模拟生产环境数据盘
[root@db01 ~]# fdisk -l
Disk /dev/sda: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x0003ac1e
Device Boot Start End Blocks Id System
/dev/sda1 * 2048 411647 204800 83 Linux
/dev/sda2 411648 2050047 819200 82 Linux swap / Solaris
/dev/sda3 2050048 41943039 19946496 83 Linux
Disk /dev/sdb: 5368 MB, 5368709120 bytes, 10485760 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
2. 格式化磁盘并挂载
2.1 创建一个数据目录data
[root@db01 ~]# mkfs.xfs /dev/sdb
[root@db01 ~]# mkdir -p /data/mysql/data
2.2 挂载数据目录
[root@db01 ~]# blkid #<==设备格式化完了后,会产生一个唯一的UUID
/dev/sda1: UUID="21cdab80-c67c-4a8c-9e92-038cbf81c3cc" TYPE="xfs"
/dev/sda2: UUID="ace0ad34-e3c5-43c5-9227-cb1a1ff2730f" TYPE="swap"
/dev/sda3: UUID="04ab5cae-4e35-41f1-a0da-33f81ef641dd" TYPE="xfs"
/dev/sr0: UUID="2018-11-25-23-54-16-00" LABEL="CentOS 7 x86_64" TYPE="iso9660" PTTYPE="dos"
/dev/sdb: UUID="3ea41b5f-f467-4c4e-9dce-9b348e472864" TYPE="xfs" #<==复制sdb的UUID
[root@db01 ~]# echo 'UUID=3ea41b5f-f467-4c4e-9dce-9b348e472864 /data xfs defaults 0 0' >> /etc/fstab
[root@db01 ~]# vim /etc/fstab
#
# /etc/fstab
# Created by anaconda on Sun Apr 28 22:28:16 2019
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=04ab5cae-4e35-41f1-a0da-33f81ef641dd / xfs defaults 0 0
UUID=21cdab80-c67c-4a8c-9e92-038cbf81c3cc /boot xfs defaults 0 0
UUID=ace0ad34-e3c5-43c5-9227-cb1a1ff2730f swap swap defaults 0 0
UUID=3ea41b5f-f467-4c4e-9dce-9b348e472864 /data xfs defaults 0 0
"/etc/fstab" 12L, 595C written
[root@db01 ~]# mount -a
[root@db01 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 20G 5.1G 14G 27% /
devtmpfs 476M 0 476M 0% /dev
tmpfs 487M 0 487M 0% /dev/shm
tmpfs 487M 7.6M 479M 2% /run
tmpfs 487M 0 487M 0% /sys/fs/cgroup
/dev/sda1 197M 133M 64M 68% /boot
tmpfs 98M 0 98M 0% /run/user/0
/dev/sdb 5.0G 33M 5.0G 1% /data
3. 授权
[root@db01 ~]# chown -R mysql.mysql /application/*
[root@db01 ~]# chown -R mysql.mysql /data/mysql/data
2. 初始化数据库
共有两种方法
5.6版本的数据库初始化命令
/application/mysql/scripts/mysql_install_db --user=mysql --datadir=/application/mysql/data --basedir=/application/mysql
5.7版本数据库,拥有全新的密码安全机制
mysqld --initialize --user=mysql --basedir=/application/mysql --datadir=/data/mysql/data
参数说明:
--initialize参数:
- 密码复杂度:12位,字母、数字、特殊字符
- 密码过期时间:默认180天
- 初始化完后,会生成临时密码,显示在屏幕上,并且会往日志中记录一份。初始化命令如下:
方法1:
[root@db01 ~]# mysqld --initialize --user=mysql --basedir=/application/mysql --datadir=/data/mysql/data
mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory
上述初始化命令回车后报错,原因是:error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory(加载共享库时出错:libaio.so。1:无法打开共享对象文件:没有这样的文件或目录)Linux系统中缺少libaio-devel 软件包
解决方法如下:
[root@db01 ~]# yum install -y libaio-devel
方法2:
始化数据,初始化管理员的密码为空
mysqld --initialize-insecure --user=mysql --basedir=/application/mysql --datadir=/data/mysql/data
参数说明:
--initialize-insecure:无限制,无临时密码
[root@db01 ~]# mysqld --initialize-insecure --user=mysql --basedir=/application/mysql --datadir=/data/mysql/data
2019-06-13T06:25:11.669931Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2019-06-13T06:25:12.179867Z 0 [Warning] InnoDB: New log files created, LSN=45790
2019-06-13T06:25:12.304339Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2019-06-13T06:25:12.391800Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: ffe55c30-8da3-11e9-8813-000c29577287.
2019-06-13T06:25:12.393402Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2019-06-13T06:25:12.394536Z 1 [Warning] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
[root@db01 /data/mysql/data]# ll
total 110628
-rw-r----- 1 mysql mysql 56 Jun 13 14:25 auto.cnf
-rw-r----- 1 mysql mysql 419 Jun 13 14:25 ib_buffer_pool
-rw-r----- 1 mysql mysql 12582912 Jun 13 14:25 ibdata1
-rw-r----- 1 mysql mysql 50331648 Jun 13 14:25 ib_logfile0
-rw-r----- 1 mysql mysql 50331648 Jun 13 14:25 ib_logfile1
drwxr-x--- 2 mysql mysql 4096 Jun 13 14:25 mysql
drwxr-x--- 2 mysql mysql 8192 Jun 13 14:25 performance_schema
drwxr-x--- 2 mysql mysql 8192 Jun 13 14:25 sys
初始化完成后,虽然root没有密码,但是,5.7.20的新特性就是,初始化完了后数据库的状态是只能允许本地登录的。
3. 书写默认配置文件
[root@db01 /data/mysql/data]# vim /etc/my.cnf
[mysqld]
user=mysql
basedir=/application/mysql
datadir=/data/mysql/data
server_id=6
port=3306
socket=/tmp/mysql.sock
[mysql]
socket=/tmp/mysql.sock
prompt=3306 [\d]>
4. 配置CentOS6模式的启动脚本(sys-v:service):
[root@db01 /application/mysql/support-files]# ./mysql.server start
Starting MySQL.Logging to '/data/mysql/data/db01.err'.
.. SUCCESS!
[root@db01 /application/mysql/support-files]# cp mysql.server /etc/init.d/mysqld
[root@db01 /etc/init.d]# cd
[root@db01 ~]# service mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
[root@db01 ~]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
[root@db01 ~]#
[root@db01 ~]# service mysqld stop
Shutting down MySQL.. SUCCESS!
5. 配置systemd方式启动
[root@db01 ~]# cat >/etc/systemd/system/mysqld.service <<EOF
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/application/mysql/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE = 5000
EOF
[root@db01 ~]# systemctl start mysqld
[root@db01 ~]# lsof -i :3306 #<==检测数据库启动是否成功
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 9174 mysql 31u IPv6 41022 0t0 TCP *:mysql (LISTEN)
[root@db01 ~]# netstat -lntup|grep mysqld
tcp6 0 0 :::3306 :::* LISTEN 9174/mysqld
[root@db01 ~]# netstat -lntup|grep 3306
tcp6 0 0 :::3306 :::* LISTEN 9174/mysqld
[root@db01 ~]# ps -ef | grep mysqld | grep -v grep
mysql 9174 1 0 15:12 ? 00:00:00 /application/mysql/bin/mysqld --defaults-file=/etc/my.cnf
[root@db01 ~]# ss -lntup|grep 3306
tcp LISTEN 0 80 :::3306 :::* users:(("mysqld",pid=9174,fd=31))
6. 数据库更改密码
方法1:
[root@db01 ~]# mysqladmin -uroot -p password oldboy123
Enter password: #<==刚开始的时候数据库是没有密码的,这里直接回车就行
[root@db01 ~]# mysql -uroot -p
Enter password:
#省略若干行
3306 [(none)]>
方法2:忘记MySQL root密码,如何更改
1.先关闭数据库
2.启动数据库到维护模式
[root@db01 /application]# systemctl stop mysqld
[root@db01 /application]# mysqld_safe --skip-grant-tables --skip-networking & #<==完了后会停在这里,直接回车几下
[root@db01 /application]# mysql
3306 mysql> alter user root@'localhost' identified by '1';
ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement
3306 mysql> flush privileges;
3306 mysql> alter user root@'localhost' identified by '1';
Query OK, 0 rows affected (0.01 sec)
关闭数据库,正常启动验证
[root@db01 /application]# mysql #<==由于没有输入密码,所以不能登入
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
[root@db01 /application]# mysql -uroot -p
Enter password: #<==密码为刚刚设置的1
3306 [(none)]>
如何分析处理MySQL数据库无法启动,错误如下:
解决方法:查看日志
日志位置:/data/mysql/data/主机名.err
直接查看关键字[ERROR]上下文
报错可能情况:
/etc/my.cnf 路径不对等
/tmp/mysql.sock文件做过修改或删除过
数据目录权限不是mysql,也会报错
my.cnf参数写错
3、MySQL体系结构介绍
1.MySQL体系结构与管理
1.1 MySQL C/S结构介绍
MySQL C/S结构在Linux平台下默认提供了两种连接方式
方式1:
TCP/IP方式(远程、本地):
mysql -uroot -poldboy123 -h 10.0.0.51 -P3306
方式2:
Socket方式(仅本地):
mysql -uroot -poldboy123 -S /tmp/mysql.sock #<==该启动模式完全依赖于socket文件,socket文件是启动时生成的,正常关闭后消失,如果非正常删除,可能会导致socket文件不会自动消失,从而导致数据库异常。还有就是,socket文件是不能更改和删除的,不然也会导致数据库启动异常。远程连接无法使用该文件。
1.2 MySQL 实例的构成
公司:老板 + 经理 + 员工 + 办公室
实例:mysqld后台守护进程 + Master Thread + 干活的Thread+预分配的内存
1.2.1 MySQL程序运行原理
1.2.1.2 mysqld程序结构
1.3 MySQL 中mysqld服务器进程结构
1.3.1 SQL语句引入
结构化的查询语言(专门对数据库进行管理、操作的语言)
如下:
3306 [(none)]>select user,host from mysql.user;
+---------------+-----------+
| user | host |
+---------------+-----------+
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+---------------+-----------+
3 rows in set (0.03 sec)
3306 [(none)]>
常用的结构化查询语言格式:
DQL(Data Query Language):数据查询语言--->select
DDL(Data Definition Language):数据定义语言--->create、drop、alter(用于操作对象及对象本身,这种对象包括数据库,表对象,及视图对象)
DML(Data Manipulation Language):数据操作语言--->inster、update、delete(用于操作数据库对象对象中包含的数据)
DCL:数据控制语言--->grant,commit,rollback
思考:select user,host from mysql.user;从开始执行到执行完毕,这个过程是怎么样的?
执行过程如下:
(1)连接层
(2)SQL层
(3)存储引擎层
1.3.2. 连接层
(1)由连接层提供两种连接协议
TCP/IP
Socket
(2)验证用户密码的合法性,与专门的授权表进行匹配,(5.7以前的版本启动时会把授权表加载到内存中,因为存储引擎是MyISAM的缘故)
MySQL用户的组成:root@localhost
(3)派生一个专用的连接线程(接收SQL语句并返回结果)
查看连接线程:(每开一个新窗口登录数据库,都会新增一个线程,这个线程是由Master生成的)
3306 [(none)]> show processlist; #<==查看线程语句
+----+------+-----------+------+---------+------+----------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------+------+---------+------+----------+------------------+
| 4 | root | localhost | NULL | Query | 0 | starting | show processlist |
+----+------+-----------+------+---------+------+----------+------------------+
1 row in set (0.00 sec)
思考:忘记密码后,改密码的参数如何运行:
--skip-grant-tables:在连接层跳过授权表匹配(不进行用户名、密码验证)
--skip-networking:在连接层跳过TCP/IP连接的方式,只通过Socket方式连接(为了安全,因为没有密码)
1.3.3 SQL层执行过程(优化方面至关重要)
(1)验证SQL语法的正确性和SQL_MODE
(2)验证语义(要干什么),这个时候它会与DQL、DML、DDL、DCL进行匹配,看属于哪一类的SQL语句
(3)将SQL语句进行HASH运算,生成一个值(SQL ID,字母数字的组合),然后与查询缓存进行匹配,看有无相同SQL ID,如果有相同的SQL ID,将直接返回结果给连接层的线程,然后再由连接层线程返回给客户端,如果SQL ID没有匹配上,就交由下一层继续处理
(4)验证SQL的权限
(5)解析器进行语句解析(预处理 ),生成执行计划(解析树)
(6)优化器(各种算法,5.7使用的是基于执行代价的模型),根据算法找到代价最低的执行计划。但是优化器选出来的方法不一定是最好的。这个时候就需要人为的修改优化器的算法,来找到我们想要的执行方法。
## 何为代价:根据CPU、IO、MEM资源的消耗来执行算法
(7)执行器按照优化器选择执行计划,执行SQL语句,得出获取数据的方法
(8)提供query cache(查询缓存。默认没有开启),一般不开,用redis代替
(9)记录操作日志(binlog,只记录修改类的操作)默认不开启
1.3.4 存储引擎层
## 真正和磁盘打交道的一个层次
根据SQL层提供的获取数据的方法拿到数据,然后返回给SQL层,结构化成表的形式,再由连接层的线程返回给用户。另外,还会在SQL层的缓存层加上这个SQL ID。到这里,SQL语句基本执行完毕。