May 5, 2017·4 min read·engineeringrqlitegobuilds

rqlite moves its release build to Go 1.8.1

rqlite 3.14.0 changes the toolchain used for its release binaries. Go's HTTP redirect changes show why a compiler and standard-library update can affect database protocol behavior.

A database release can change behavior without adding a database command. The compiler, runtime and standard library are part of the executable that handles requests and coordinates nodes. rqlite 3.14.0, published on 5 May, is the project's first release built with Go 1.8. Its tagged changelog names the precise toolchain as Go 1.8.1.

The release has a single changelog entry, the toolchain switch in pull request 304. That limited application diff does not make the build environment irrelevant. rqlite's HTTP clients and server rely on standard-library behavior, and its Go runtime remains present while the process applies commands and serves queries.

I value the simplicity of distributing a small database executable. That simplicity makes the provenance of the executable more important, since the user is adopting the runtime and libraries selected by the builder along with the application code. The version of Go installed separately on the host is a different fact.

The build selects an exact distribution

The release's CircleCI configuration sets GODIST to go1.8.1.linux-amd64.tar.gz. Its setup step obtains that archive and installs it as the Go distribution used by the job. The version selection is explicit in build configuration rather than inferred from a generic machine image.

The test commands print go version, run formatting checks and invoke vet. Two parallel CI branches run ordinary tests and race-enabled tests, with different timeouts. Those commands document what the project's build checks at this tag. They do not provide performance results for the new release.

The contribution guide now requires Go 1.8 or later for building. It describes the GOPATH directory layout and the SQLite driver used by the project. It also notes that repeatedly compiling SQLite support can make local rebuilds slow, and describes preinstalling that dependency to reduce repeated work.

Those details separate two kinds of build cost. The Go toolchain compiles the surrounding application, while SQLite support contributes its own compilation work. A release note saying that the project moved to Go 1.8.1 should not be read as a claim that the database engine's SQL implementation was rewritten in Go.

Standard-library changes can affect the protocol

The Go 1.8 release notes document a relevant HTTP change. Client.Post now follows 301 redirects and converts them to GET requests without a body. Previously that automatic behavior applied to 302 and 303 responses. Go 1.8 also adds handling for 307 and 308 redirects that preserves the original method and body when the request supports resending it.

For rqlite, a redirect is part of locating the leader. A SQL request contains a body that must remain meaningful when the client contacts the destination. Allowing a general HTTP client to convert a POST into a bodyless GET can interfere with that application protocol.

The rqlite changelog records an earlier correction in 3.13.0 that makes the CLI handle redirects explicitly because of Go 1.8. That preparation is part of the context for adopting the new build toolchain. Application-level redirect handling lets rqlite retain the request semantics it needs instead of inheriting a changed default unnoticed.

I find this example more useful than treating a compiler update as an administrative detail. The language can remain compatible while standard-library behavior changes in a way that matters to a distributed service. The relevant compatibility question includes what requests the resulting binary sends on the network.

Runtime changes need bounded claims

Go 1.8 also removes stop-the-world stack rescanning from garbage collection. Its release notes describe shorter pauses and link the underlying design. That is relevant background for any long-running Go service, including one serving requests while maintaining replicated state.

It does not establish a particular improvement in rqlite latency. The runtime change and an application's observed request distribution are different evidence. The rqlite release announcement gives no workload or latency measurements, so a numerical claim about database performance would go beyond its sources.

The Go notes also describe reduced deferred-call overhead and broad standard-library optimizations. These changes explain why adopting a toolchain can alter execution cost even when the application diff is small. They remain runtime-level changes until measurements connect them to a particular database workload.

The published artifact is the release change

The release page gives download instructions for binaries and describes starting a single node. The contribution guide covers building from source. These are different ways to obtain an executable, and the announcement specifically identifies the toolchain used for this release's build.

The changelog labels the release 4 May, while the public release page records 5 May. This post follows that public announcement date. Its subject is the build transition itself, including the exact Go 1.8.1 selection and the standard-library redirect behavior that the preceding rqlite release had already addressed.