01 快速上手数据库安装部署
你好,我是俊达。今天我们开始MySQL运维课程的第一讲,快速上手数据库安装部署。
你可能会有一些疑问,现在云数据库发展得这么好,只需要在云平台下单,就能自动获取一个安装配置好的数据库。就算不用云数据库,企业内部多半也会有一些运维管理平台,可以按需创建数据库环境。为什么还要学数据库安装这么基础的知识?
对这个问题我是这么理解的:首先,安装数据库是了解一个数据库的第一步。通过安装部署,你可以了解数据库的核心组件,数据库由哪些文件组成,服务是怎么启动和停止的。
其次,要深入掌握一门数据库技术,离不开大量的实践操作。你在文档或书籍上看到的知识,需要在真实的数据库环境中进行测试验证,这不仅能验证你看到的内容是否正确,也能加深你对相关知识的理解。所以你需要从零开始搭建数据库、创建用户、配置数据库、搭建数据库高可用环境,测试和验证数据库的各种功能。
最后,虽然云数据库已经将大量数据库运维管理的动作自动化了,但是背后还是需要有人去设计和运维云平台本身,而你将来可能就是云数据库背后的那个人。而且,在工作中,你可能需要解决不同环境下的各种千奇百怪的数据库问题。系统地掌握数据库从安装部署到运维管理整个环节,能帮你更好地应对各种环境下的复杂问题。
接下来我们分别来学习二进制安装、RPM包安装和源码编译安装这几种安装方式。我们使用CentOS 7.9操作系统来运行MySQL。请记住, 我们的目标并不仅仅是安装MySQL,而是通过安装部署来深入理解MySQL的运行方式。
二进制安装
使用二进制包安装MySQL是比较常用的一种方式,主要分为六个步骤。
- 获取二进制安装包。
- 创建运行MySQL的用户。
- 规划数据目录,准备my.cnf参数文件。
- 初始化数据库。
- 启动数据库服务。
- 设置数据库初始密码。
第一步:获取二进制安装包
先到MySQL官网下载二进制安装包,选择8.0 GA最新版本,当前8.0最新GA版本是8.0.39。
注:MySQL一般3个月左右出一个新的小版本,你看到这里的时候,可能又出了新的版本,但基本上不影响文章后面的讨论。
使用二进制安装时,操作系统选择“Linux - Generic”,操作系统版本要根据系统的glibc版本来选择,我们可以使用一些方法来确定glibc的版本,比如通过ldd命令。
可以先用浏览器下载安装包,再上传到服务器,也可以直接在服务器上使用wget、curl等工具下载。
安装包下载完成后使用md5sum工具检查文件校验码是否和官网上提供的一致。
# md5sum mysql-8.0.39-linux-glibc2.17-x86_64.tar.xz
1c092c3814b10bfa0794077867f9f4ad mysql-8.0.39-linux-glibc2.17-x86_64.tar.xz
如果一切正常,解压二进制包,将解压后的文件夹放到一个安装目录下,这里我们将安装包放到/opt目录下,并创建一个软链接。
# tar xvf mysql-8.0.39-linux-glibc2.17-x86_64.tar.xz
# mv mysql-8.0.39-linux-glibc2.17-x86_64 /opt
# ln -s /opt/mysql-8.0.39-linux-glibc2.17-x86_64 /opt/mysql80
到这里,MySQL软件其实就已经安装好了。接下来,我们熟悉一下MySQL安装目录下都有哪些文件。
bin目录下包含MySQL的服务端和客户端,以及一些命令行工具。lib目录中有MySQL客户端库,使用C API访问MySQL数据库时,需要用到这里面的库文件。lib目录下还有一个plugin目录,存放着MySQL的各类插件,包括我们在后续课程中会介绍的CLONE插件、半同步插件、组复制(MGR)插件。include目录下是C API的头文件,编译访问MySQL的C代码时会用到这些文件。share目录下有一些运行MySQL需要用到的文件,如不同语言的错误日志信息文件、字符集的定义文件。
下面表格对其中一些重要文件做了简单介绍。
第二步:创建运行MySQL的用户
出于安全考虑,我们需要创建一个单独的用户来运行MySQL。
第三步:规划数据目录,准备my.cnf参数文件
我们需要规划一个数据目录,用来存放MySQL的数据文件,以及各类日志文件。如果你部署的MySQL将用于生产,那么我建议你使用满足一定性能要求的磁盘设备,如SSD,以保障性能。
这里提供一种我平时使用的目录规划方式。
# tree -d -L 2 /data
/data
|-- mysql3306
| |-- binlog
| |-- data
| |-- log
| |-- relaylog
| |-- run
| `-- tmp
|-- mysql3307
| |-- binlog
| |-- data
| |-- log
| |-- relaylog
| |-- run
| `-- tmp
其中data是挂载点,把文件系统挂载到/data。每个实例的所有文件,都放在同一个顶层目录中,以 mysql{$PORT}
的方式命名。data目录用来存放数据库的数据文件。binlog和relaylog目录分别用来存放binlog和relaylog。log目录存放日志文件,包括错误日志、慢SQL日志。run目录存放pid文件和sock文件。tmp目录用来存放MySQL运行过程中可能会产生的临时文件。配置文件my.cnf存放到实例的顶层目录中。
在这个目录规划下,一个基本的配置文件如下:
## /data/mysql3306/my.cnf
[mysql]
socket=/data/mysql3306/run/mysql.sock
[mysqld]
port=3306
mysqlx_port=33060
basedir=/opt/mysql80
lc_messages_dir=/opt/mysql80/share
datadir=/data/mysql3306/data
tmpdir=/data/mysql3306/tmp
log-error=/data/mysql3306/log/alert.log
slow_query_log_file=/data/mysql3306/log/slow.log
general_log_file=/data/mysql3306/log/general.log
socket=/data/mysql3306/run/mysql.sock
innodb_data_file_path=ibdata1:128M:autoextend
innodb_buffer_pool_size=2G
第四步:初始化数据库
使用mysqld初始化数据库,第一个参数必须是defaults-file,指向上一步准备好的my.cnf配置文件,第二个参数是initialize,指示mysqld进行初始化操作。
初始化可能需要一定的时间,完成后会在数据目录(datadir)下生成默认数据库和相关的系统表。
# tree -L 1 -u -h -F /data/mysql3306/data
/data/mysql3306/data
|-- [root 576K] #ib_16384_0.dblwr
|-- [root 8.6M] #ib_16384_1.dblwr
|-- [root 4.0K] #innodb_redo/
|-- [root 4.0K] #innodb_temp/
|-- [root 56] auto.cnf
|-- [root 1.7K] ca-key.pem
|-- [root 1.1K] ca.pem
|-- [root 1.1K] client-cert.pem
|-- [root 1.7K] client-key.pem
|-- [root 5.8K] ib_buffer_pool
|-- [root 128M] ibdata1
|-- [root 4.0K] mysql/
|-- [root 25M] mysql.ibd
|-- [root 4.0K] performance_schema/
|-- [root 1.7K] private_key.pem
|-- [root 452] public_key.pem
|-- [root 1.1K] server-cert.pem
|-- [root 1.7K] server-key.pem
|-- [root 4.0K] sys/
|-- [root 16M] undo_001
`-- [root 16M] undo_002
如果初始化没有成功,需要到错误日志中查看相关的报错信息,进行相应的处理。错误日志的路径由配置文件中的参数log-error指定。初始化成功后,可以看到错误日志的最后一行输出的mysql root账号的临时密码,我们要用这个密码来登录数据库。
# tail -10 /data/mysql3306/log/alert.log
2024-06-24T01:56:48.849579Z 0 [System] [MY-013169] [Server] /opt/mysql80/bin/mysqld (mysqld 8.0.39) initializing of server in progress as process 5352
2024-06-24T01:56:48.863677Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2024-06-24T01:57:30.863543Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2024-06-24T01:57:55.476711Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: YB%OojGi85?L
数据库初始化完成后,就可以启动了,不过在启动前,还需要做一件事情。如果初始化数据库时使用了Linux的root账号,还需要把mysql目录下的文件owner修改成mysql。
第五步:启动数据库服务
我们有几种不同的方式来启动MySQL服务,下面的例子使用mysqld_safe脚本来启动MySQL,使用defaults-file指定参数文件的路径。
# /opt/mysql80/bin/mysqld_safe --defaults-file=/data/mysql3306/my.cnf &
[1] 5569
# mysqld_safe Logging to '/data/mysql3306/log/alert.log'.
mysqld_safe Starting mysqld daemon with databases from /data/mysql3306/data
如果启动失败,需要到错误日志中查看具体的报错信息。比较常见的问题有端口已经被占用了,或者参数文件中参数名写错了。
# tail -10 /data/mysql3306/log/alert.log
2024-06-24T02:17:43.215483Z 0 [ERROR] [MY-010262] [Server] Can't start server: Bind on TCP/IP port: Address already in use
2024-06-24T02:17:43.215527Z 0 [ERROR] [MY-010257] [Server] Do you already have another mysqld server running on port: 3306 ?
2024-06-24T02:17:43.215560Z 0 [ERROR] [MY-010119] [Server] Aborting
2024-06-24T02:17:45.035093Z 0 [System] [MY-010910] [Server] /opt/mysql80/bin/mysqld: Shutdown complete (mysqld 8.0.39) MySQL Community Server - GPL.
MySQL服务启动成功后,可以在错误日志中看到“ready for connections”的日志信息。
[Server] /opt/mysql80/bin/mysqld: ready for connections. Version: '8.0.39' socket: '/data/mysql3306/run/mysql.sock' port: 3306 MySQL Community Server - GPL.
第六步:设置数据库初始密码
MySQL在数据库初始化时设置了一个临时密码,可以在错误日志中找到。
# grep password /data/mysql3306/log/alert.log
2024-06-24T01:57:55.476711Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: YB%OojGi85?L
使用临时密码登录数据库后,执行SQL会提示要先修改密码。
# mysql -uroot -h127.0.0.1 -p'YB%OojGi85?L'
mysql> select now();
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
使用alter user命令修改mysql root账号的密码后,就可以正常使用数据库了。
mysql> alter user 'root'@'localhost' identified by 'Abcd1234';
Query OK, 0 rows affected (1.45 sec)
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2024-06-24 11:09:23 |
+---------------------+
1 row in set (0.00 sec)
这就是使用二进制方式安装MySQL的整个过程,可以看到过程并不复杂。使用二进制安装的主要优点就是你可以很方便地部署多实例,在同一台服务器运行多个版本的MySQL,可以方便地规划磁盘路径。
RPM安装
使用Linux的包管理器安装MySQL也是一种比较常用的方式,这里我们以CentOS 7.9为例来简单说明安装过程。
第一步:下载RPM包
选择8.0当前的最新版本。由于我们使用了CentOS 7.9,操作系统选择“Red Hat Eenterrise Linux / Oracle Linux”,操作系统版本选择“Red Hat Enterprise Linux 7 / Oracle Linux 7(x86,64-bit)”。
下载mysql-8.0.39-1.el7.x86_64.rpm-bundle.tar,里面包含了安装MySQL需要的所有rpm包。
下载完成后验证md5,并解压。
# md5sum mysql-8.0.39-1.el7.x86_64.rpm-bundle.tar
1f59378ee4a9b40791672eed61366f52 mysql-8.0.39-1.el7.x86_64.rpm-bundle.tar
# tar xf mysql-8.0.39-1.el7.x86_64.rpm-bundle.tar
第二步:处理有冲突的包
如果服务器上已经安装了其他版本的MySQL或MariaDB的RPM包,就有可能会和待安装的RPM包发生冲突,需要先把这些RPM包卸载掉。注意,在生产环境卸载已经安装的包可能会引起问题,需要在服务器上线前就处理好这些问题。
# rpm -qa | egrep -i 'mysql|mariadb'
mariadb-libs-5.5.68-1.el7.x86_64
# yum remove mariadb-libs
Resolving Dependencies
......
Removed:
mariadb-libs.x86_64 1:5.5.68-1.el7
Dependency Removed:
postfix.x86_64 2:2.10.1-9.el7
第三步:安装RPM包
使用RPM命令安装RPM包,把server、client以及依赖的lib包都安装上。
# rpm -ivh mysql-community-libs-8.0.39-1.el7.x86_64.rpm \
mysql-community-client-8.0.39-1.el7.x86_64.rpm \
mysql-community-libs-compat-8.0.39-1.el7.x86_64.rpm \
mysql-community-client-plugins-8.0.39-1.el7.x86_64.rpm \
mysql-community-server-8.0.39-1.el7.x86_64.rpm \
mysql-community-common-8.0.39-1.el7.x86_64.rpm \
mysql-community-icu-data-files-8.0.39-1.el7.x86_64.rpm
warning: mysql-community-libs-8.0.39-1.el7.x86_64.rpm: Header V4 RSA/SHA256 Signature, key ID a8d3785c: NOKEY
Preparing... ################################# [100%]
Updating / installing...
1:mysql-community-common-8.0.39-1.e################################# [ 14%]
2:mysql-community-client-plugins-8.################################# [ 29%]
3:mysql-community-libs-8.0.39-1.el7################################# [ 43%]
4:mysql-community-client-8.0.39-1.e################################# [ 57%]
5:mysql-community-icu-data-files-8.################################# [ 71%]
6:mysql-community-server-8.0.39-1.e################################# [ 86%]
7:mysql-community-libs-compat-8.0.3################################# [100%]
第四步:启动MySQL服务
RPM包安装成功后,就可以使用service命令启动MySQL服务了。
使用RPM安装的MySQL,默认的错误日志文件路径为/var/log/mysqld.log。如果无法正常启动MySQL服务,可以到错误日志中查看相关报错信息。
# tail -100 /var/log/mysqld.log
......
2024-06-24T04:34:12.995336Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.39' socket: '/var/lib/mysql/mysql.sock' port: 3306 MySQL Community Server - GPL.
2024-06-24T04:34:12.995347Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
第五步:修改数据库默认密码
和二进制安装一样,使用RPM安装的MySQL,第一次访问时,也需要先修改数据库的默认密码。先从错误日志中找到临时密码。
# grep password /var/log/mysqld.log
2024-06-24T03:56:57.469312Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: ,6R&fqlf/5TS
再使用临时密码登录数据库,执行alter user命令修改密码。密码修改后,数据库就可以正常使用了。
# mysql -uroot -h 127.0.0.1 -p',6R&fqlf/5TS'
mysql> select 1;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
mysql> alter user 'root'@'localhost' identified by 'Abcd1234';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
mysql> alter user 'root'@'localhost' identified by 'ComplexPassword2024$';
Query OK, 0 rows affected (0.45 sec)
mysql> select 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)
注意,使用RPM包安装的MySQL,增加了数据库账号密码强度的验证。
二进制安装和RPM安装的区别
我们来对比下二进制安装和RPM包安装这两种安装方式的主要区别。
使用二进制安装时,我们需要做更多的准备工作,包括创建MySQL操作系统账号、创建数据库相关目录、准备参数文件。而使用RPM包安装时,自动包含了这些初始化动作。
使用二进制安装时,我们需要先创建初始化数据库。而使用RPM安装的MySQL,把初始化数据库的操作放到了service的启动脚本中。
# more /usr/lib/systemd/system/mysqld.service
[Service]
User=mysql
Group=mysql
......
# Needed to create system tables
ExecStartPre=/usr/bin/mysqld_pre_systemd
# Start main service
ExecStart=/usr/sbin/mysqld $MYSQLD_OPTS
执行service start mysql命令启动MySQL服务时,脚本mysqld_pre_systemd会检查数据目录是否存在,如果数据目录还没有创建,就会创建目录,并执行数据库初始化。并且mysqld_pre_systemd在初始化数据库时,还执行了下面这个SQL,启用了密码验证组件。
INSERT INTO mysql.component (component_id, component_group_id, component_urn) VALUES (1, 1, 'file://component_validate_password');
启用密码验证组件后,在MySQL中创建账号或修改账号密码时,需要使用有一定复杂度的密码。
二进制安装时,MySQL程序安装在一个统一的目录中,比如我们使用的/opt/mysql80。而使用RPM安装时,将MySQL程序安装在不同的路径下。mysqld安装在/usr/sbin路径下,其它程序安装在/usr/bin路径下,库文件安装在/usr/lib64/mysql下,字符集等相关支持文件放在/usr/share/mysql-8.0路径下。
二进制安装时,我们把参数文件、数据目录和其他运行MySQL的文件都放到了 /data/mysql{$PORT} 路径下,而RPM安装时,my.cnf默认放到/etc,数据目录放到/var/lib/mysql,错误日志使用了/var/log/mysqld.log。
如果你有单机多实例,或者在单台服务器上运行多个MySQL版本的需求,使用二进制安装更方便。
源码编译安装
通常我们会选择使用官方提供的二进制版本来部署MySQL,但是有些情况下也可能会采用源码编译的方式。比如,在一些信创环境下,官方可能没有提供目标系统的二进制安装包。或者我们需要安装一些非标准版本的MySQL,可能需要安装一些社区的patch、bugfix、扩展插件。或者想使用其他编译器或编译选项来编译MySQL,比如使用Intel的C编译器。或者出于学习的目的编译Debug版本的MySQL,用来调试一些功能。
第一步:准备build环境
编译MySQL本身不复杂,不过需要先准备好一个编译环境。编译MySQL 8.0需要以下几个基本工具。
- cmake3
- binutils
- gcc 7.1以上版本
- openssl
- ncurse
CentOS 7.9默认的GCC版本太老了,需要安装一个新版本的GCC。当然你也可以使用其它的Linux发行版本。
安装cmake3。
安装GCC。
yum install centos-release-scl
yum install devtoolset-11-gcc devtoolset-11-gcc-c++ devtoolset-11-binutils
安装其它依赖库。
第二步:下载源码
在MySQL的下载页面,操作系统选择“Source Code”,操作系统版本选择“All operating Systems (Generic) (Architecture Independent)”。选择带C++ boost库的源码包,编译MySQL时需要这些代码。
源码下载后,先验证一下文件校验码,确认没问题后再解压文件。
# wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-boost-8.0.39.tar.gz
# md5sum mysql-boost-8.0.39.tar.gz
07ee1d23908fc4ad7fc6a5cb8f2c99de mysql-boost-8.0.39.tar.gz
# tar zxf mysql-boost-8.0.39.tar.gz
# tree -d -L 1 mysql-8.0.39
mysql-8.0.39
|-- archive_output_directory
|-- bin -> ./runtime_output_directory
|-- boost
|-- client
|-- cmake
|-- CMakeFiles
|-- components
|-- Docs
......
第三步:构建MySQL二进制
进入源码目录,这里我们演示使用cmake3来构建一个Debug版本的MySQL。如果执行cmake报错,需要查看错误信息,并做相应的处理。
# cd mysql-8.0.39
# cmake3 -DWITH_DEBUG=ON \
-DWITH_BOOST=boost/boost_1_77_0 \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql8.0
构建MySQL有很多选项,这里我介绍其中最基础的几个选项,完整的选项你可以到 官方文档 中查看。
cmake成功后,使用make命令构建MySQL,使用参数 -j 指定编译的并发数,可以根据机器的配置选择合适的并发数,以加快构建的速度。
第四步:安装二进制
构建成功后,使用make install命令将MySQL安装到CMAKE_INSTALL_PREFIX指定的路径下。
我们的例子中,MySQL安装到了/usr/local/mysql8.0下。
# tree -L 1 /usr/local/mysql8.0/
/usr/local/mysql8.0/
├── bin
├── docs
├── include
├── lib
├── LICENSE
├── mysql-test
├── README
└── share
我们构建出来的mysqld占用的空间比较大,如果要用在生产环境,可以使用strip命令对可执行文件进行裁剪,去掉二进制文件中的一些符号和调试信息。
# ls -lSh bin
total 1.2G
-rwxr-xr-x 1 root root 707M Jun 24 18:26 mysqld
-rwxr-xr-x 1 root root 39M Jun 24 17:47 mysqlxtest
-rwxr-xr-x 1 root root 22M Jun 24 17:39 mysqlpump
-rwxr-xr-x 1 root root 21M Jun 24 17:39 mysqlbinlog
......
### 使用strip减少文件大小
# strip mysqld
# ls -lSh
total 565M
-rwxr-xr-x 1 root root 128M Jun 25 10:32 mysqld
-rwxr-xr-x 1 root root 39M Jun 24 17:47 mysqlxtest
-rwxr-xr-x 1 root root 22M Jun 24 17:39 mysqlpump
-rwxr-xr-x 1 root root 21M Jun 24 17:39 mysqlbinlog
二进制文件安装完成后,接下来的步骤和“二进制安装”中的步骤没有区别,这里就不再重复了。
总结时刻
这一讲我们学习了在Linux操作系统下安装MySQL的几种方法。如果你需要安装部署大量MySQL服务器,我个人比较推荐使用二进制的方式安装。你需要制定一个标准规范,包括二进制安装路径、数据文件存放路径、服务器和数据库的标准参数配置等,并且按这个标准来部署所有的MySQL环境。
思考题
早期的版本中,登录服务器本地的MySQL默认不需要密码。这存在一定的安全风险,因为你只要能登录到数据库服务器,就能访问这台服务器上的MySQL数据库。从5.7版本开始,给数据库的root账号设置了默认密码,首次登录时需要先修改密码。在部署一套MySQL数据库环境时,小明按规范修改了数据库root账号的密码,但是当时忘了将root密码记录下来,因此小明向你寻求帮助。你有办法帮小明解决这个问题吗?
欢迎你把你的答案分享到评论区,如果你觉得这节课的内容对你有帮助的话,也欢迎你分享给其他朋友,我们下节课再见!