mysql57 on Windows-Server-Core

Update

我将完整的项目放在github上了,如果有需要的话可以自取。

背景

由于原来的数据服务器配置较低,数据库服务最近总是将CPU吃满(即使是在没有查询的时候,这点比较奇怪),不过正好重新申请了一台配置更高的服务器,系统为windows server 2016,本着方便的目的,准备使用docker部署。安装好docker之后,切换到linux container的时候提示hyper-V有一个组件没有启动,手动删除hyper-V,准备重装的时候,遇到错误:处理器没有所需要的虚拟化功能。估计是因为宿主机器没有开启嵌套虚拟化,导致服务器无法启动hyper-V。服务器本身就是在云平台上启动的虚拟机,虽然说windows server 2016是提供了嵌套虚拟化的,不过应该不是默认开启,跟技术提供方交流沟通了一下也没有什么后续。
查阅了一些资料,windows上的docker虚拟机是提供两种运行时,分别是windows server container和hyper-v container,其中windows server container是windows近几年提供的一种容器技术,与底层操作系统共享内核,所以仅能运行windows应用;hyper-V则是在宿主机上启动新的虚拟机,虚拟机具备独立的操作系统内核,所以可以运行linux下的程序。在windows上安装docker后,会有一个container的选择,使用windows container或者linux container。如果选择使用linux container,则必须启动hyper-V服务,因为linux container的实现实际上是在hyper-V中启动一个linux虚拟机,然后将镜像运行在虚拟机中;而如果选择使用windows container,则不一定需要启动hyper-V服务。鉴于此,我就选择服务器上的docker使用windows container,希望这样能通过绕过hyper-V从而不用管宿主机是否开启了嵌套虚拟化功能,这样做的坏处就是,只能使用基于windows-servercore的镜像,并且,mysql官方组是没有提供基于windows-servervcore的mysql镜像,只能自己在windows-servercore的基础上创建编译镜像,好在微软在git上提供了一组windows-container-samples,可以参照一下,下面就开始构建自己的mysql:5.7.22的镜像。

准备工作

  1. 下载windows server core的镜像:docker pull microsoft/windowsservercore,需要注意的是:“Windows requires the host OS version to match the container OS version”,所以在windows server 2016上也就只能运行2016的镜像。这个镜像居然有好几个G,还总在下载过程中失去连接,吐血,最后折腾了一个下午,终于在服务器上下载完了。为了避免以后再次出现这样下载时总断掉连接的情况,我将下载好的镜像导出为tar文件,导出的文件居然有10G,再次吐血。
  2. 确认mysql安装包的下载地址:在微软提供的样例中,mysql使用的是5.6.29版本,而需要安装的mysql是5.7的,所以不能直接使用微软提供的下载地址,需要在oracle上找到mysql5.7的安装包,确认下载地址

工作进行时

  1. 仿照微软提供的样例,在dockerfile中将mysql的下载地址和解压缩名称修改为需要版本的地址和名称,然后构建镜像
  2. Sadly,mysql 5.7.6之后的安装方式有所变化:解压出来的文件中不再包含data文件夹和my.ini文件,需要手动创建my.ini文件并在文件中指定相应的data目录,然后运行mysqld初始化数据库以后才可以正常安装MySQL服务。再Sadly的是,不知道是什么原因,容器中运行mysqld没有输出,即使手动创建了data目录和my.ini文件,执行mysqld --initialize也不会有输出,我已经将这个问题开了issue反馈到微软的git上了,不知道何时能够解决。 (Update:问题已经定位并且解决了,具体见后文)
  3. 因为刚刚中提到的问题,我只能使用微软提供的样例dockerfile构建镜像,即使用MySQL 5.6版本。
  4. 构建好镜像,运行容器,在做端口映射时又遇到了问题:
    Docker run …. -p 0.0.0.0:3306:3306
    Windows 不支持这样的端口映射,直接使用-p 3306:3306即可,使用host IP:port即可实现外部访问容器,而在host上访问docker却不能使用127.0.0.1:3306,要使用命令:docker inspect --format '{{ .NetworkSettings.Networks.nat.IPAddress }}' <container>来获得容器的IP地址,然后使用container IP:port才能访问容器,具体可参见这篇博客
  5. 在挂载数据卷时,又遇到了问题:Docker run … -v volume:mysql data directory会报错,因为server 2016不能将数据卷挂载到一个非空目录(具体可以参见这篇博客),官方提出的解决办法是在构建的时候删掉欲挂载的目录。。。emmm,那我这mysql初始化的数据咋办,犹豫再三,还是决定在服务器上直接装mysql服务。
    官方提供的解决办法

峰回路转

在出现以上问题后,我犹豫再三,还是决定放弃docker,直接在服务器上安装mysql5.7,但是!服务器上在使用mysqld命令初始化的时候,报错,缺失msvcr120.dll这个动态链接库,点击了提示框的确定之后,命令行也没有任何错误输出,我突然就想到,会不会windows-server-core上也是同样的问题!在一番查询之后,我在微软官方下载这个动态链接库的网页中看到,

“这些组件是在未安装 Visual Studio 2013 的计算机上运行使用 Visual Studio 2013 开发的应用程序所必需的。”

mysql5.7可能是使用VS2013编译,那么在没有安装VS2013的机器上就没有相应的DLL,服务器是完整的windows server 2016,都没有这些库,那么windows-server-core上肯定也是没有的!如果他们缺失的库是相同的,那么把这些库补齐之后,windows-server-core上就有可能能运行mysql5.7了!
为了能够完整地知道服务器上运行mysql5.7需要的动态链接库,我没有选择从官网下载vcredist_x64.exe,而是将缺失的文件一个个从本地机器复制到了服务器上,缺失的文件总共是两个:

  • msvcp120.dll
  • msvcr120.dll

在服务器上成功的安装了mysql5.7之后,我又尝试在windows-server-core中安装。因为windows-server-core仅是保证基础的功能,有可能缺失更多的文件,但是由于windows-server-core没有GUI,缺失的文件具体是什么也无从得知,所以也不能保证加入了这两个动态链接库之后,windows-server-core就能成功安装mysql5.7了。但是!事实证明,windows-server-core确实是只缺少这两个动态链接库!将这两个文件复制到容器的C:\windows\system32目录下,重新执行mysqld --initialize就能成功执行初始化了!(前提是有my.ini文件)

总结

至此,服务器上安装mysql服务总算是圆满成功了(流下感动的泪水)!经过这一番折腾,我对windows server有了新的认识:都用windows server了,还用什么命令行啊!windows下的程序开发者肯定也没有想到,有一天居然会有人在纯命令行下使用windows,还要安装他们的服务,他们甚至连命令行运行程序出现的错误信息都要有GUI才能看到!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值