I have a 16-gigabyte database on a cloud machine, accessible through an OpenVPN tunnel, and a duplicate of that database on my laptop. The problem has always been:
loading it. Until now, that required making a mysqldump file, FTP'ing it to the laptop, and loading the file.
Today I started wondering ... might it somehow be possible to connect to my laptop's database (on its VM), through the tunnel,
from the cloud machine, without requiring any privileged commands? I decided to find out.
First, I looked at the particulars of the tunnel.
ifconfig utun0 included a line that looked like
11.8.0.14 ---> 11.8.0.11, which, is it turns out, means that "my laptop" when connected through OpenVPN has an address of
11.8.0.14 on the virtual private subnet.
I tried to
ping the address, and found that it worked. So, next, I tried to use the Swiss-Army-Knife tool,
nc == netcat.
- On my laptop, in the host (not the VM's) operating system, I ran: nc -l 1234.
- Then, on the cloud, I tried to connect: nc 11.8.0.14 1234 ...
- And it worked. What I typed on one console appeared on the other and vice versa.
But how to make a
two-way connection? Somehow, I had to get these packets to port
3306 of my VM at
192.168.56.101 ... and back again.
Of course, one way to do it is with (probably, privileged) commands, on whatever-is your operating system, to set up "port forwarding." But, I wanted to do it "on the cheap," without issuing special commands.
This XiNote provided the answer. From a terminal window on my laptop host, I typed:
Code:
mkfifo backpipe
while true
do
nc -G 9999 -l 1234 0<backpipe | nc -G 9999 192.168.56.101 3306 1>backpipe
done
With that command running, I could now on the cloud machine connect to IP-address
11.8.0.14 port
1234, and issue my MySQL commands directly. To actually load the data, I used the MySQL
source filename; command on a previously-prepared
mysqldump. The critical difference is: that gigantic dump-file never leaves the cloud server.
(The commands will end when the connection is closed.)
An endless loop is used to immediately restart the command when it ends, since each run of the
mysqldump command, e.g. to load separate table files that have been "split out" from the gigantic MySQL dump, requires a new connection. (A one-second "sleep" is inserted in the script on the remote side, specifically to give this loop plenty of time to restart.)
OpenVPN delivers the traffic securely to port #1234 which is being listened-to by the command given above. It is forwarded to port #3306 on my virtual machine ... which, of course, is the standard MySQL port. Returning traffic goes the opposite way.
Although obviously it
still takes a long time to move 16 gigabytes of data from here to there, the process got the job done.
The
-G 9999 option for
nc specifies a 9999-second timeout
(not sure if that's mandatory) so that the connection never drops even if a particular query takes a long time. (There are also "keep-alive" options, but they pick up OS defaults and I never had to use them.)
The
--compress option on MySQL makes a big difference, because OpenVPN is relatively slow while MySQL query text is quite compressible. It reduces the operation time by about two-thirds.
Nevertheless: the overall result was an
enormous time-saver over the previous process that I had to do.
Quote:
"Man! I feel like a hack-er!"
|