如何在Docker中设置和配置MySQL

MySQL是最受欢迎的关系型数据库工具,市场份额超过40%。与竞争对手PostgreSQL(16%)和Oracle数据库(11%)相比,它的数字看起来非常不错。

MySQL因其简单而强大而受欢迎。以下是它的最佳特点:

  • 关系型:遵循关系模型并使用SQL来管理数据库。
  • 开源(GNU许可证):社区喜欢它。公司也喜欢它。
  • 可扩展:可以处理从小型到企业级的应用程序。
  • 安全:提供用户认证、访问管理和加密。
  • 高性能:以处理复杂查询和大量数据而闻名于世。
  • 复制和备份:它具有数据复制和备份选项,可以实现灾难恢复策略。

至于在Docker容器中使用MySQL,那简直是天作之合。如果你以前使用过Docker,那么所有它的好处也适用于MySQL的Docker容器:

  • 隔离和一致性:MySQL实例将与其他软件和依赖项隔离开来,防止潜在的冲突。
  • 版本控制:Docker允许您对整个软件堆栈以及MySQL进行版本控制。这意味着您可以随时重现您的环境,便于开发和测试。
  • 可扩展性和资源管理:使用Docker,您可以通过轻松分配更多的资源(如内存或CPU)来扩展您的MySQL应用程序。
  • 依赖管理:Docker封装了您的MySQL实例,使您能够管理不同版本的MySQL而不会影响本地机器上的任何内容。

最重要的是,您的MySQL应用程序可以在任何地方运行,而不仅仅是在您的计算机上。

所以,今天你将学习如何将MySQL与Docker一起运行的基础知识。让我们开始吧!

前提条件

由于本文重点介绍MySQL Docker容器,因此需要满足以下几个前提条件:

  • 命令行/终端访问:您需要一个具有终端访问权限的本地环境。如果您在像Colab这样的Jupyter环境中,请立即切换。
  • 正在运行的Docker实例:您应该已经安装了Docker Desktop(在我们的Docker数据科学教程中有说明)。当它完全运行时,界面的左下角将显示一个绿色的小鲸鱼图标:

image2.png

并且在终端上使用docker --help命令时没有错误。

  • 对Docker有基本的了解:尽管我会解释文章中使用的所有命令,但对Docker有基本的了解将显著增加您从本文中获得的好处。
  • SQL:对于SQL也是如此 – 我不会解释本文中使用的任何SQL命令,因为这会偏离主题。如果您的SQL技能有点生疏,您可以回顾一下这个SQL课程中最重要的主题。

下载官方MySQL Docker镜像

我们将通过以下命令下载官方MySQL Docker镜像:

$ docker pull mysql:latest

docker pull 命令需要使用 image:version 语法指定镜像的名称和版本。使用关键字 latest 可以下载最新的稳定版本。

如果您访问Docker Hub上的官方MySQL镜像页面,您可以看到许多其他用于不同目的的版本。

image3.png

这段文字的中文翻译如下:

以下是下载v8.2的示例:

$ docker pull mysql:8.2

一旦你下载了镜像,它应该会列在你现有的Docker镜像中:

image4.png

这段文字的中文翻译如下:

通过终端也可以列出Docker镜像:

$ docker images

image5.png

记住: Docker镜像是构建容器的蓝图。就像蓝图可以帮助你建造房子一样,Docker镜像包含了创建应用程序或服务运行实例所需的所有指令和组件。

如果你来自面向对象编程(OOP)的背景,可以将Docker镜像视为类。就像创建一个类可以创建多个对象一样,Docker镜像允许你创建多个容器。

运行和管理MySQL服务器容器

现在,让我们从mysql镜像创建我们的第一个容器。以下是我们将使用的命令:

$ docker run --name test-mysql -e MYSQL_ROOT_PASSWORD=strong_password -d mysql
  • run:创建一个新的容器或启动一个已存在的容器
  • --name CONTAINER_NAME:为容器指定一个名称。名称应该易读且简短。在我们的例子中,名称是test-mysql
  • -e ENV_VARIABLE=value:使用-e标签创建一个环境变量,该变量可以在容器内部访问。设置MYSQL_ROOT_PASSWORD非常重要,这样我们才能从容器中运行SQL命令。确保将强密码存放在安全的地方(不是你的脑子里)。
  • -d:缩写形式的detached,-d标签使容器在后台运行。如果移除此标签,命令会一直打印日志,直到容器停止。
  • image_name:最后一个参数是容器将要构建的镜像名称。在这个例子中,我们的镜像是mysql

如果命令返回一长串无意义的字符(容器ID),说明容器已经启动。你可以使用docker ps命令来检查容器的状态:

image6.png

这段文字的中文翻译如下:

记住: Docker容器是一个强大的操作系统仿真器。除了运行MySQL,您还可以在容器内执行您通常会在计算机终端上执行的任何任务。

要访问容器内的终端,您可以使用以下命令:

$ docker exec -it container_name bash

这将启动一个bash会话。

本地连接到MySQL服务器容器

所有MySQL容器都启动了一个包含了使用SQL创建和管理数据库所需的一切的MySQL服务器。为了连接到服务器,容器还配备了一个MySQL客户端,让我们可以运行SQL查询。客户端只是mysql终端命令的一个花哨的名称。让我们在test-mysql的终端中使用它:

1. 打开test-mysql的bash终端:

$ docker exec -it test-mysql bash

2. 以 root 用户身份连接到客户端:

$ mysql -u root -p
输入密码:...
mysql>

我们使用-u标签来指定用户名(root),并添加-p标签以在提示时输入密码。

image1.gif

这段文字的中文翻译如下:

也可以在容器外连接到MySQL服务器。例如,您可以在主机上手动安装MySQL客户端来进行连接。

要在Windows上安装MySQL及其客户端,您可以按照官方MySQL安装指南的说明进行操作。

对于Mac用户,您可以使用Homebrew:

$ brew install mysql

对于Linux或WSL2(我的选择),你可以使用sudo

$ sudo apt update
$ sudo apt install mysql-client

安装完成后,如果您正在运行容器,请停止并删除它:

$ docker stop test-mysql
test-mysql
$ docker rm test-mysql

接下来,我们将通过将容器的端口映射到本地机器上的一个端口来重新启动容器:

$ docker run -d --name test-mysql -e MYSQL_ROOT_PASSWORD=strong_password -p 3307:3306 mysql

这个命令执行以下操作:

  • -p 3307:3306:将容器的端口3306(MySQL的默认端口)映射到本地端口3307。这意味着发送到本地端口3307的任何流量都将转发到容器的端口3306,并且您的MySQL服务器将在该端口上可访问。
  • -d:再次以分离模式运行容器。
  • --name test-mysql:重用相同的容器名称”test-mysql”。
  • -e MYSQL_ROOT_PASSWORD=strong_password:再次为MySQL服务器设置root密码。
  • mysql:指定要运行的Docker镜像,即官方的MySQL镜像。

终端输出新的容器ID后,我们可以检查端口映射:

$ docker port test-mysql
3306/tcp -> 0.0.0.0:3307

翻译结果:成功了!现在,你可以从本地机器上使用mysql客户端连接到端口3307上的服务器:

$ mysql --host=127.0.0.1 --port=3307 -u root -p
输入密码:

欢迎使用 MySQL monitor。命令以;或\g结尾。
您的 MySQL 连接 ID 为 8
服务器版本:8.2.0 MySQL Community Server - GPL

版权所有 (c) 2000, 2023, Oracle 和/或其附属公司...

配置 MySQL 容器

您可以使用配置文件来配置 MySQL 容器的许多设置。通常,该文件将存储在容器的以下一个目录中:

  • /etc/mysql/
  • /etc/mysql/conf.d
  • /etc/mysql/mysql.conf.d

这些目录会因图像而异。但配置文件的标准文件名和扩展名是my.cnf。如果文件在上述任何目录中都不存在,则表示容器需要一个自定义配置文件。这是我们的test-mysql容器的情况:

$ ls /etc/mysql/conf.d/ # 返回无输出

在这种情况下,我们必须采取以下谨慎的步骤:

1. 停止并移除容器:

$ docker stop test-mysql; docker rm test-mysql

2. 在本地(您的计算机上)创建一个空的配置文件:

$ sudo mkdir -p /etc/docker/test-mysql # 创建一个目录
$ sudo touch /etc/docker/test-mysql/my.cnf # 在目录中创建一个配置文件

3. 通过链接两个空的.cnf文件来重新启动容器:

$ docker run \
   --name test-mysql \
   -v /etc/docker/test-mysql:/etc/mysql/conf.d \
   -e MYSQL_ROOT_PASSWORD=strong_password \
   -d mysql

我们正在编写一个新的标签:-v,它是卷的缩写。该标签可用于在容器和本地机器之间链接目录。在计算机科学术语中,这个过程被称为挂载

所以,在上面的命令中,我们将本地的/etc/docker/test-mysql目录挂载到容器的/etc/mysql/conf.d目录。这将链接两个目录的内容。在任何一个目录中进行的更改都会反映在另一个目录中。挂载允许我们在本地编辑my.cnf文件,以更改Docker容器的配置。最好的部分是,即使容器停止或删除,修改后的配置也将在我们的本地机器上保留下来。它将是可重复使用的。

所以,在这一步之后,我们可以更改哪些配置?答案取决于您的使用情况。我们将在下面进行介绍。

你应该配置哪些选项?

虽然MySQL Docker容器的默认配置适用于许多常见场景,但你应该修改某些设置以优化性能、安全性和资源使用情况。以下是一些最常更改的配置选项:

性能

  • innodb_buffer_pool_size:此设置确定分配给InnoDB缓冲池的内存量,该缓冲池用于缓存频繁访问的数据以加快检索速度。增加此值可以改善读取密集型工作负载的性能,但也会消耗更多内存。
  • query_cache_size:此设置控制查询缓存的大小,该缓存存储先前执行的查询以便更快地重新执行。增加此值可以改善重复查询的性能,但也会消耗更多内存,并且对于动态查询可能不起作用。
  • thread_pool_size:此设置确定服务器可以处理的最大并发连接数。根据预期的流量负载调整此值可以优化资源利用并防止瓶颈。

安全性

  • bind-address:此选项限制MySQL服务器仅在特定网络接口上侦听,限制未经授权的访问。
  • mysql_bind_host:此设置允许将MySQL服务器绑定到特定的IP地址,而不是在所有接口上侦听。
  • validate_password_policy:此选项启用更严格的密码要求以提高安全性。

资源利用

  • max_connections:此设置控制允许的最大并发连接数。调整此值可以防止资源耗尽并确保服务器的高效运行。
  • innodb_file_per_table:此选项将每个InnoDB表存储在单独的文件中,可能提高性能,但增加了存储空间要求。
  • innodb_io_capacity:此选项设置存储系统的预估IOPS(每秒输入/输出操作数),使引擎能够优化缓冲池使用和磁盘操作。

其他常见修改

  • character_set_server:此选项设置服务器的默认字符集,确保数据编码和处理的一致性。
  • collation_server:此选项确定用于字符数据排序和比较的默认排序规则。
  • log_bin:此选项启用服务器活动的二进制日志记录,对于故障排除和复制非常有帮助。

要查看完整的配置选项列表,可以运行以下命令:

$ docker run -it --rm mysql:tag --verbose --help

您可以使用任何文本编辑器编辑 .cnf 文件。以下是您应该遵循的语法:

如何保留存储在MySQL Docker容器中的数据

保留存储在MySQL容器中的数据对于许多原因至关重要:

[mysqld]
max_connections=200
other_params=value
...

Persisting data stored in your MySQL containers is crucial for many reasons:

  • 数据持久化:当您停止或删除容器时,所有数据都会丢失,包括您的数据库。将数据与容器分离使其始终可访问。
  • 在容器之间共享数据:将数据与容器分离,允许多个容器访问它。这样,您可以避免数据重复,并简化使用相同数据的项目之间的同步。
  • 可移植性和备份:持久化数据可以轻松备份和独立共享,提供可靠的方式来恢复数据丢失或意外删除。
  • 改进的性能和可扩展性:通过将频繁访问的数据存储到持久存储器(如SSD)中,与依赖容器的可写层相比,可以提高应用程序的性能,后者通常较慢。

这个过程与我们已经看到的一样 – 我们将创建一个卷并将其挂载到容器中存储数据的位置。以下是步骤:

1. 创建一个卷:

$ docker volume create test-mysql-data

`volume create` 命令在本地文件系统上创建一个专用的存储空间用于存储卷。卷挂载后,所有容器数据将与其关联。

2. 重新启动已挂载卷的容器:

$ docker stop test-mysql; docker rm test-mysql
$ docker run \
   --name test-mysql \
   -v test-mysql-data:/var/lib/mysql \
   -e MYSQL_ROOT_PASSWORD=strong_password \
   -d mysql

这次,语法的格式是:-v volume_name:directory_in_container。所有创建的卷都应该按照MySQL镜像文档中指定的方式挂载到/var/lib/mysql目录上。

所以,现在,在test-mysql内创建的任何数据库或表都将在容器停止或删除后保留在本地。

最终命令

在整篇文章中,我们的docker run命令已经发生了很大的变化。因此,让我们将所有的变化整合到一个最终的主命令中。我们需要再次停止和删除容器。我们还将删除卷,以便从头开始:

$ docker stop test-mysql; docker rm test-mysql
$ docker volume rm test-mysql-data

所以,这是最终的主命令:

$ docker run \
   --name final-mysql \
   -e MYSQL_ROOT_PASSWORD=strong_password \
   -p 3307:3306 \
   -v /etc/docker/test-mysql:/etc/mysql/conf.d \
   -v final-mysql-data:/var/lib/mysql \
   -d mysql

这个命令将我们之前的my.cnf本地文件挂载到指定位置,并创建一个名为final-mysql-data的新卷并挂载它。

结论

本文涵盖了在Docker容器中运行和管理MySQL数据库的基本方面。我们学习了如何下载和设置MySQL镜像,如何在容器内启动MySQL服务器,如何修改这些容器并添加卷以进行自定义配置和数据持久化。

要了解更多关于这个主题的信息,我推荐以下资源:

感谢阅读!

抱歉,我无法翻译视频和图片标签,也无法保留代码块。以下是我对文本的翻译:

“你是一个翻译员。”