虚拟主机 / 内网进行数据库管理的几个还不错的方案

背景

前面其实有文章提到,为了方便运维(更重要的原因是便宜),我的网站、服务通常是部署在虚拟主机上的。


虚拟主机一般会有配置赠送一些数据库空间,比如百度云 BCH,提供了 1G 的免费 MySQL,日常情况下也够用了,所以一般情况下,我也不需要额外再购买 MySQL 数据库,而是直接使用虚拟主机附赠的就成。


但是,虚拟主机赠送的数据库一般也会有较多的限制,空间、内存等各个方面,这些其实也还好,本来就没指望能性能怎么好。但是有个最大的问题是,数据库通常不提供外网访问。比如百度云,就是提供了一个 PhpMyAdmin 的界面方便我们进行管理。那么,如果我临时需要查看或者修改一下数据库里面的内容,就需要登录百度云 -> 找到虚拟主机 -> 进入对应的控制面板 -> 找到数据库管理入口,再进去管理。更麻烦的是,页面一段时间没操作,登录就过期了,就还得再重新来一次。


这种情况可能还不止虚拟主机会遇到,有时候,一些特定网络下的机器也会有类似的限制。例如,办公网段和线上服务器网段进行了隔离,就需要用一些跳板机、代理,或者专用的数据库管理平台进行维护,Navicat 这一类的数据库客户端也是无法使用的。当然,这一类情况下,我的建议是遵循规定,不要想着绕过去了。

解决登录容易过期的问题

先看百度云现在的方案,是基于 PhpMyAdmin 进行管理,只是这个登录验证很容易失效。如果说只是对这一点感觉麻烦,数据库的操作还是愿意基于网页版来操作的话,最简单的方案就是自己也部署一套 PhpMyAdmin。


为了方便运维,也可以把 PhpMyAdmin 部署到一个单独的文件夹,用单独的域名来访问。这个可以参考我之前的文章《Nginx 虚拟主机支持多域名部署》。


除了我们耳熟能详的 PhpMyAdmin,其他也有 Adminer、phpMiniAdmin、SQL Buddy 等轻量级的工具,也能实现这样的效果。甚至有的工具只有 1 个 php 文件,非常适合快速部署、快速销毁。


包括 PhpMyAdmin 在内,我试用了下,基本都可以做到比百度云默认提供的工具更方便。

image.png

如果想用客户端呢?

页面操作,总归还是比较麻烦,不如用客户端方便。


开始,我有个思路。比如说,我在虚拟主机上部署一套代码,仿照 MySQL 一样,去提供基于 TCP 的对外接口。但是很快就排除掉了这个想法,并不是因为实现复杂,而是虚拟主机就不给你用类似 listen 这样的方法去监听端口,提供 server 的能力。甚至有的虚拟主机,连 tcp client 的代码都无法执行。


百度云 BCH 还算厚道,tcp client 能执行,但是 server 的能力总归是不可能提供的。


于是我用类似 mysql http 代理之类的关键词到百度去搜,噫,意外地发现 Navicat 竟然默认已经提供了类似的功能。


在 Navicat 安装目录,可以找到类似于 ntunnel_mysql.php 这样的文件,将其部署到虚拟主机上,在 Navicat 里面就可以使用了。


创建连接的时候,有一个“HTTP”的选项卡,可以配置 php 部署的路径。简单配置之后就可以使用了。试了一下,效果还是不错的,操作就和默认的 TCP 连接差不多。


image.png


因此,如果日常使用的客户端软件就是 Navicat,那么这个方案直接就能解决问题。

其他的客户端管理软件呢?

Navicat 毕竟是一个收费的软件,我日常其实用的不是它,而是免费的 DBeaver。DBeaver 是不支持 http tunnel 这种方式的,甚至还可以在 github 的 dbeaver 仓库下,看到有不少人提了类似的 issue(https://github.com/dbeaver/dbeaver/issues/4445),官方目前觉得不合适提供。


OK,继续想想有什么办法呢?


其实前面一开始我想到的,去在虚拟主机上部署一套代码支持 mysql 以 TCP 方式进行连接,这个方案可以再换个思路:虚拟主机上无法部署,那我是不是可以在本地启动一个 server 模拟 mysql server,再让这个 server,内部以 http 接口的方式去和虚拟主机上的 php 代码来交互?


直觉上,这个方法是可行的。而且虚拟主机上的 php 代码,其实我们完全可以复用 Navicat 的 ntunnel_mysql.php 代码。这样就省得我们再自己想一套交互协议了,而且 php 的代码也自然不用写了。这个 ntunnel_mysql.php 配合 Navicat 用得也挺好的,估计没啥大问题。


稍微看了下 ntunnel_mysql.php 的代码,其实也挺简单的,最核心的逻辑就是把语句执行的结果,进行拼装、打印。


我各种代码也都能写,php 虽然算是我的最爱,但考虑到本地执行 server 的便捷性,反而第一个被排除了。比如我用 swoole 或者 Workerman 写一个 tcp 的 server,那如果换一台电脑想执行,总归还是需要 php 的环境。java、python 相对都好一些,可以想办法打成免依赖即可执行的文件。


结果呢,世事难预料啊!我继续在网上搜,发现了一个  https://github.com/polarrwl/hersql  工具,感觉像是随手传到了 github 上,按照说明(非常简略)看,可能实现的也是我想要的功能。


Go 代码我是真不熟。。没办法,边试边学呗。毕竟 Go 代码想要提供可执行文件就可太方便了,跨平台使用也没问题。

遇到的一些问题

下载下来之后,发现编译还挺好,没啥报错就编译好了,也能跑起来。


但是,试着用 DBeaver 和 Navicat 去连接之后,发现用不了,报了错误:

no dsn specified before the query:..., you can try restarting the mysql client


看起来是在执行 sql 语句前,没有初始化“DSN”信息。所谓 DSN,就是对数据库的一些描述,比如数据库服务器地址(host)、端口(port)、用户名、密码,甚至包括数据库名等。从代码看,这个 DSN 信息在执行了“USE”语句的时候(比如选择了哪个数据库)会自动执行。


可是 DBeaver、Navicat,到底在连接数据库的时候,执行哪些语句,这个我们无法控制。我猜测,可能这个代码针对以前的 Navicat 版本是可以使用的?不过,这个不重要,重要的是现在遇到这个问题要怎么解决。


这个工具提供的样例配置里面,只有 ntunnel_mysql 的访问地址,而没有提供用户名、密码等配置信息,不太清楚是不是以前的 Navicat 配置时,这些信息会转化成初始化的 DSN 配置传进来。那么如果现在没有的话,我干脆就把这个放到配置文件里面直接指定吧。于是,我就在配置里面加上了这些默认信息。如果 DSN 连接没有初始化,那就用配置里面的数据库信息,先初始化一次。


再继续用,发现针对一些数据量比较小的数据表没问题了,但是访问一些数据量稍微大一点的,就有新的错误:

Reader.parseBlockValueWithFirstByte read value n:[1] != [19]


这个错误是在 hersql 通过 http 请求获得了 response 之后,解析的过程中报出来的。既然 ntunnel_mysql.php,在 Navicat 里面直接用 http 连接的方式用得好好的,那我自然还是宁可相信,它返回的内容本身没问题,还是 hersql 自己解析时候有 bug。


于是又系统地学习了一下 go 语言里面 http 请求、reader 之类的知识,把 response 打印出来一点点定位。

经过艰苦地定位,并没有找到原因,但是。。。莫名其妙地好了 -____-!!!(猜测可能和拼接的 http request,或者是这些 response 的 byte 转换、解析有关,但既然好了。。就也不想再继续折腾了)

最终方案

因此,经过一番定位、修复,这个工具重新可用了。


我也把一些代码进行了重构后,放回了 github(https://github.com/poisonbian/hersql),也发布了一个 release,方便大家可以直接下载可执行文件来使用。


欢迎大家试用并 Star!


本文链接:https://poisonbian.com/post/5045.html 转载需授权!

分享到:
原文链接:,转发请注明来源!
「虚拟主机 / 内网进行数据库管理的几个还不错的方案」评论列表
moris_chang@qq.com
moris_chang@qq.com
发布于 2025-06-12 10:56:22  回复
请问在本地电脑通过MSSM修改数据库可以吗 我这样做之后发现网站没有更新
poisonbian
poisonbian
发布于 2025-06-17 11:26:39  回复
可以的啊。不过网站没有更新,会不会和其他原因有关,比如缓存?

发表评论