Using Docker to Create Pop-Up MySQL Instances

Pop-Up shops are those short lived stores at malls and other places, often times they are kiosks. They serve as to satisfy temporal demands like nano quadcopters or engraved keychains. In this context you can create MySQL instances that are short lived, easily provisioned, and easily disposed of.

Imagine you are a developer, or the DBA who has to tell a developer when their code breaks, and you would like an easy way to validate code against the production schema, but not impact your production systems?

This recipe makes some assumptions:

  • You have a MySQL slave or a secondary Innodb Cluster instance to CLONE from
  • You are using MySQL 8.0.17 or later
  • You don’t have hundreds of gigabytes to terabytes of data

If you have a lot of data in your production environment, this won’t be a viable solution, but if your data is in the 10s of gigabytes, this could work for you.

I’m going to present 2 options: 1) A completely standalone transient instance of MySQL 2) A semi-persistent instance of MySQL that can live on an external encrypted SSD or other secured storage.

Continue reading “Using Docker to Create Pop-Up MySQL Instances”

WebCom secrets: How we hosted 70,000 domains on one Apache instance

A chief virtue of time is that it provides distance. Time is the 4th dimension we live in and it gives us the opportunity to share what once was, without fear of reprisal. It has been 12 years since I was let go from Verio, almost as much time as I worked for WebCom/Verio/NTT. I feel there is enough distance between then and now to share some secrets without fear of reprisal.

WebCom did things differently, we pioneered name-based virtual hosting and we learned how to do more with less. Back when WebCom was starting to do name-based hosting it was common for many providers to put 2,000 IP addresses on an SGI machine running IRIX. I assume that the allure of SGI had to do with decent horsepower and a BSD derived OS that could host a lot of IP addresses per NIC. Back then the BSD network stack was considered to be one of the best.

When I started we had HP PA-RISC machines, a Sun 4/330, and a Windows NT 3.51 486 running MS SQL Server (Sybase). By the end of the year we’d signed a lease on a Sun Enterprise 1000 server, a piece of “big iron” at the time. I think we had 4 SuperSPARC processors and 512MB of RAM. We looked at offering IP based hosting on Sun, but their OS only allowed up to 255 IPs per NIC. We briefly considered an inexpensive array of SCO Unix boxes, but Linux was never in the running because Chris considered it an immature OS. I spent my entire career there championing Linux, and winning.

We decided to go the Big Ole Server route with Sun, first with the S1000E, then an Enterprise 4000 in 1997. Early on we ran Netscape Enterprise Server, a commercial web server product from Netscape, written by the same people who wrote NCSA httpd. This was a modular web server with a plugin architecture and it could be expanded by writing NSAPI modules to perform actions in the chain of operations. Apache wasn’t really on the radar at this point. Chris wrote the first name-based hosting plugin for Netscape, this solution lasted us until around 20,000 domains, then the underlying architecture of Netscape became a bottleneck.

Continue reading “WebCom secrets: How we hosted 70,000 domains on one Apache instance”

MySQL 8 Network Backup Using Docker and CLONE

One of the shortcomings of MySQL GPL is that it does not come with a first party online backup solution. With the release of MySQL 8.0.17 the CLONE plugin was introduced, this essentially integrated online backup as a plugin to the MySQL Server.

The MySQL 8.0 Reference Manual describes how to use the CLONE plugin to perform local clones (backups) here: https://dev.mysql.com/doc/refman/8.0/en/clone-plugin-local.html

Doing local clones is incredibly useful and a really fast way of making an image backup. I would argue that the CLONE plugin is better for local image backups than competing solutions simply because the syntax is more brief and efforts were made to integrate CLONE into the server, thereby reducing the impact of performing CLONE operations.

The CLONE plugin can either clone to the server’s default data directory or to another directory specified in the CLONE command. I will demonstrate the latter usage for making online remote backups without modifying the data directory of the container.

Continue reading “MySQL 8 Network Backup Using Docker and CLONE”

Bona Fides: Linux Kernel

This page shouldn’t be considered a brag page, it’s just a place for me to easily categorize a Linux Kernel contribution I made eons ago. This is my original contribution of the vfork(2) system call. The current Linux kernel does not implement it in this way, however syscall 190 is still sys_vfork 😄

Subject: [PATCH] new syscall: sys_vfork
To: linux-kernel@vger.rutgers.edu (Linux Kernel Mailing List)
Date: Fri, 8 Jan 1999 10:49:54 -0800 (PST)
X-Mailer: ELM [version 2.4 PL24]
Content-Type: text
Status: RO
Content-Length: 5783
Lines: 156

Hello,

Well, I hacked in support for a traditional style vfork.  I haven't
tried actually running an application using the new vfork; I wanted
to release what I have to get feedback, as this is the first patch
I've really done.

Anyhow, some background first:

This implementation of vfork supports these features:

 - the VM is cloned off the parent
 - the parent sleeps while the vfork()ed child is running
 - the parent awakes on an exec() and exit()
 - the implementation theoretically allows for recursive vforks
 - it's executable from within a cloned thread
 - If I'm right about the flags, the sigmask is not cloned

A little bit about the 'controversial' parts:  The implementation
uses a wait queue in the task structure.  When the parent vforks,
after successful spawning, it sleeps on the vfork wait queue.  When
the child exits or execs, it does a wake_up(&current->p_pptr->vfork_sleep);
Which causes the parent to awake.  The wakeup in the exec is right
at the top of do_execve().  The wakeup in exit is right before
the time the parent gets notified of the child exit (before notify_parent);

It allows recursion because if a vforked child vforks, it just sleeps,
and as each vforked child performs an exec or exit, it percolates up
through the vfork execution stack.

Please let me know if I've done anything grossly wrong, or just wrong.
Additionally, could someone tell me how to do direct syscalls, I'm fuzzy
on that ;)

--Perry

------------------------------8<-----------------------------------------------

diff -u --recursive linux.vanilla/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- linux.vanilla/arch/i386/kernel/entry.S      Thu Jan  7 19:21:54 1999
+++ linux/arch/i386/kernel/entry.S      Thu Jan  7 20:38:18 1999
@@ -559,13 +559,14 @@
        .long SYMBOL_NAME(sys_sendfile)
        .long SYMBOL_NAME(sys_ni_syscall)               /* streams1 */
        .long SYMBOL_NAME(sys_ni_syscall)               /* streams2 */
+       .long SYMBOL_NAME(sys_vfork)            /* 190 */

        /*
-        * NOTE!! This doesn' thave to be exact - we just have
+        * NOTE!! This doesn't have to be exact - we just have
         * to make sure we have _enough_ of the "sys_ni_syscall"
         * entries. Don't panic if you notice that this hasn't
         * been shrunk every time we add a new system call.
         */ 
-       .rept NR_syscalls-189
+       .rept NR_syscalls-190
                .long SYMBOL_NAME(sys_ni_syscall)
        .endr
diff -u --recursive linux.vanilla/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- linux.vanilla/arch/i386/kernel/process.c    Thu Jan  7 19:21:54 1999
+++ linux/arch/i386/kernel/process.c    Thu Jan  7 20:33:23 1999
@@ -781,6 +781,19 @@
        return do_fork(clone_flags, newsp, &regs);
 }

+asmlinkage int sys_vfork(struct pt_regs regs)
+{
+       int     child;
+
+       child = do_fork(CLONE_VM | SIGCHLD, regs.esp, &regs);
+
+       if (child > 0) {
+               sleep_on(&current->vfork_sleep);
+       }
+
+       return child;
+}
+
 /*
  * sys_execve() executes a new program.
  */
diff -u --recursive linux.vanilla/fs/exec.c linux/fs/exec.c
--- linux.vanilla/fs/exec.c     Sun Nov 15 09:52:27 1998
+++ linux/fs/exec.c     Fri Jan  8 10:32:59 1999
@@ -808,6 +808,9 @@
        int retval;
        int i;

+       /* vfork semantics say wakeup on exec or exit */
+       wake_up(&current->p_pptr->vfork_sleep);
+
        bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
        for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
                bprm.page[i] = 0;
diff -u --recursive linux.vanilla/include/linux/sched.h linux/include/linux/sched.h
--- linux.vanilla/include/linux/sched.h Thu Jan  7 19:27:44 1999
+++ linux/include/linux/sched.h Thu Jan  7 21:57:20 1999
@@ -258,6 +258,10 @@
        struct task_struct **tarray_ptr;

        struct wait_queue *wait_chldexit;       /* for wait4() */
+
+/* sleep in vfork parent */
+       struct wait_queue *vfork_sleep;
+
        unsigned long policy, rt_priority;
        unsigned long it_real_value, it_prof_value, it_virt_value;
        unsigned long it_real_incr, it_prof_incr, it_virt_incr;
@@ -298,6 +302,7 @@
        struct files_struct *files;
 /* memory management info */
        struct mm_struct *mm;
+
 /* signal handlers */
        spinlock_t sigmask_lock;        /* Protects signal and blocked */
        struct signal_struct *sig;
@@ -349,6 +354,7 @@
 /* pidhash */  NULL, NULL, \
 /* tarray */   &task[0], \
 /* chld wait */        NULL, \
+/* vfork sleep */      NULL, \
 /* timeout */  SCHED_OTHER,0,0,0,0,0,0,0, \
 /* timer */    { NULL, NULL, 0, 0, it_real_fn }, \
 /* utime */    {0,0,0,0},0, \
diff -u --recursive linux.vanilla/kernel/exit.c linux/kernel/exit.c
--- linux.vanilla/kernel/exit.c Tue Nov 24 09:57:10 1998
+++ linux/kernel/exit.c Fri Jan  8 10:34:10 1999
@@ -292,6 +292,10 @@
                kill_pg(current->pgrp,SIGHUP,1);
                kill_pg(current->pgrp,SIGCONT,1);
        }
+
+       /* notify parent sleeping on vfork() */
+       wake_up(&current->p_pptr->vfork_sleep);
+
        /* Let father know we died */
        notify_parent(current, current->exit_signal);

diff -u --recursive linux.vanilla/kernel/fork.c linux/kernel/fork.c
--- linux.vanilla/kernel/fork.c Thu Jan  7 19:27:29 1999
+++ linux/kernel/fork.c Thu Jan  7 20:24:53 1999
@@ -521,6 +521,7 @@
        p->p_pptr = p->p_opptr = current;
        p->p_cptr = NULL;
        init_waitqueue(&p->wait_chldexit);
+       init_waitqueue(&p->vfork_sleep);

        p->sigpending = 0;
        sigemptyset(&p->signal);


------------------------------8<----------------------------------------------

Reducing the Impact of YouTube’s API Quota

I started redesigning my website a several weeks ago, my objective was to create a centralized hub for sharing written information, code, video, and photography. It was rather easy to solve most of those problems, and sharing my latest YouTube video was simple at first.

I had this niggling feeling that my new website was on the heavyweight side, after all it’s WordPress based and I had a few plugins. The annoying reCaptcha logo was popping up everywhere, even when it wasn’t used. After using the Coverage tab in Chrome and installing yet more WordPress plugins to trim the fat, I tried get it down to as small a footprint as I could. Then came the Google PageSpeed Insights. Sometimes we are blissfully unaware of our problems and go through life with blinders on, PageSpeed Insights simultaneously woke me and gave me yet another obsession to chase.

Continue reading “Reducing the Impact of YouTube’s API Quota”

Adding VGA hardware palette support

VGALIB has lead a long and meandering path, development has been an exercise of leveling up each of 3 different environments: PC hardware running DOS, SDL under Linux, and SDL under emscripten. Much of the early development was done in dosbox with the Borland C++ 3.1 IDE, but once I grew past the point of basic C++, using std::string, I had to abandon the BC3.1 IDE and go strictly to makefiles. It was during this time that using the BC3.1 IDE for editing (and it’s weird Brief key sequences) started to become an exercise in patience. I really enjoyed developing on Linux, since that’s what I’ve done for the last 25 years.

Moving to makefiles under DOS was no small feat, the issue is that dosbox is a best effort emulator for running games, but compatibility with Borland C++ 4 and later is sketchy causes crashes. I ended up creating a Windows 2000 VM with Virtualbox to compile VGALIB, but even that acts peculiar and cmd.exe requires End Task. Virtualbox doesn’t have guest additions for any 16bit legacy OSes, so Win2K is the oldest usable environment. My current development environment is Eclipse for the editing (with VIM plugin), Win2K to compile the DOS programs, and dosbox to run them. For Linux and emscripten I use Eclipse with command line make.

The reason my build environment is important to this article has to do with the development target that was most feature complete: SDL running on Linux. Palettized 8bit mode on SDL is really a pain to program to, much more so than straight RGB or RGBA, but it mimics the original IBM VGA 13h mode most closely. I implemented palette support as a matter of requirement when I added SDL support, since there there is no default palette. Until this time I hadn’t added hardware palette support to the VGA driver, I simply relied on the default VGA palette (which is fine for most things).

Continue reading “Adding VGA hardware palette support”

The Sale of WebCom

The sale of WebCom was both bitter and sweet. The sale represented independence and success for many involved, but it also was the beginning of the end. WebCom was bootstrapped from what money Chris had and some surplus equipment that we got from a customer in exchange for free hosting. That equipment lasted us until late 1995 when we needed to transition from a 486 running Windows NT 3.51 and Microsoft SQL Server, to a Sun Enterprise 1000e running Sybase SQL Server.

I mentioned before that Chris and Thomas organized the company with a 67%/33% split, eventually I would have 1%, taken from Chris’ portion, and Neal [the CFO] got 10% IIRC, of which I think Chris and Thomas gave up 5% each. After we moved to 2880 Soquel Ave, Thomas started working on his exit from the company. That exit would precipitate one of the biggest threats we ever had as a company.

Continue reading “The Sale of WebCom”