Yesterday (17/Jul/2020) I’ve added a separate feed for MySQL topics. It can be accessed at the address https://saveriomiroddi.github.io/feed/mysql.xml (also represented by the dolphin icon in the navigation bar of the blog).
Tags:announcement, assembler, awk, c, concurrency, data_types, databases, debugging, distribution, ffmpeg, filesystems, git, github, gitlab, gui, hardware, indexes, innodb, linux, media_processing, mysql, operating_systems, packaging, performance, perl, postgresql, rails, reverse_engineering, ruby, shell_scripting, small, storage, sysadmin, text_processing, ubuntu, vfio, virtualization
Modern approaches to replacing accumulation user-defined variable hacks, via MySQL 8.0 Window functions and CTEs
A common MySQL strategy to perform updates with accumulating functions is to employ user-defined variables, using the
UPDATE [...] SET mycol = (@myvar := EXPRESSION(@myvar, mycol)) pattern.
This pattern though doesn’t play well with the optimizer (leading to non-deterministic behavior), so it has been deprecated. This left a sort of void, since the (relatively) sophisticated logic is now harder to reproduce, at least with the same simplicity.
In this article, I’ll have a look at two ways to apply such logic: using, canonically, window functions, and, a bit more creatively, using recursive CTEs.
- Requirements and background
- The problem
- The old-school approach
- Modern approach #1: Window functions
- Modern approach #2: Recursive CTE
(Those looking for a ready Ruby PPA, please have a look at the announcement article )
Recently, the ubiquitous Brightbox Ruby PPA has been discontinued.
This caused a problem, because there aren’t other stable Ruby PPAs, thus requiring engineers to manually package their own Ruby.
In this article, I’ll explain how to setup a Ruby PPA and the related scripts, so that engineers can package and automatically deploy their own Ruby, and, very importantly, benefit from automated updates, virtually without any manual operation.
I’ve dealt with the PPA subject in the past; this article is an “updated, extended, and more automated version”™.
- Automating the operation
Sometimes, I want to send my display to standby, rather than the entire system. Long ago, the
xset tool alone would do the trick, but nowadays, it doesn’t.
This short article describes how to accomplish this task.
For a variety of reasons, writing (Bash) shell scripts requires lots of care. When writing non-trivial shell scripts, it’s crucial to take precautions; shell options are part of this practice.
Typically, three shell options are suggested:
pipefail, and occasionally,
However, there are other ones that developers will find important in this context:
inherit_errexit; in this article, I’ll explain them.
Another “missing and missed” functionality in MySQL is a data type for arrays.
While MySQL is not there yet, it’s now possible to cover a significant use case: storing denormalized columns (or arrays in general), and accessing them via index.
In this article I’ll give some context about denormalized data and indexes, including the workaround for such functionality on MySQL 5.7, and describe how this is (rather) cleanly accomplished on MySQL 8.0.
Another interesting feature released with MySQL 8.0 is full support for functional indexes.
Although this is not a strictly new concept in the MySQL world (indexed generated columns provided the same functionality), I find it worth reviewing, through some applications, notes and considerations.
All in all, I’m not 100% bought into functional indexes (as opposed to indexed generated columns); I’ll elaborate on this over the course of the article.
As a natural fit, generated columns are included in the article; additionally, some constructs build on my previous article, in relation to the subject of CTEs.
Updated on 12/Mar/2020: Found another bug.
- Generated columns, and their application on JSON data
- Functional indexes
- JSON functional index gotchas
- An example of functional index with dates
A long-time missing (and missed) functionality in MySQL, is sequences/ranges.
As of MySQL 8.0, this functionality is still not supported in a general sense, however, it’s now possible to generate a sequence to be used within a single query.
In this article, I’ll give a brief introduction to CTEs, and explain how to build different sequence generators; additionally, I’ll introduce the new (cool) MySQL 8.0 query hint
SET_VAR, and a pinch of virtual columns and functional indexes (“functional key parts”, another MySQL 8.0 feature).
Sometimes, either in scripts or direct commands, there is a series of repetitive, similar, commands, which could be executed in parallel.
Bash offers means for very basic parallelization (
wait), however, they’re not very practical for generic solutions.
In this article, I’ll explain how to use GNU Parallel, which makes parallelization trivial, and, as usual, introduce some other useful shell concepts.
- Using Bash built-in commands
- Enter the stage: GNU Parallel
- Escaping strings in Bash
- Sending the content of a file to a process
Considerations (review) of the ODROID H2, ODROID N2 and Raspberry Pi 4, in particular as home server
I’ve been a long time user of SBCs; as part of my equipment, I’ve always had the need for a small home server, which they fit increasingly well.
My previous SBC has been an ODROID XU4, which I’ve covered in a previous article.
I’ve been reasonably happy of it, however, my requirements overgrew its limitations, therefore, as soon as the second batch of ODROID H2 was available, I jumped at the chance to switch.
Like in the XU4 article, I will make some general considerations about small home servers and how to H2 fits the (my) requirements, and how ARM and x86 board nowadays relate.
- Part 1: History and considerations
- Part 2: The ODROID H2
- Part 3: A comparison of H2, N2 and Pi 4
- Part 4: The future
In this post I’ll expand on the subject of my MySQL pre-FOSDEM talk: what dbadmins need to know and do, when upgrading from MySQL 5.7 to 8.0.
As usual, I’ll use this post to introduce tooling concepts that may be useful in generic system administration.
- Summary of issues, and scope
- The new default character set/collation: utf8mb4/utf8mb4_0900_ai_ci
- Tooling: MySQL RLIKE
- How the charset parameters work
- String, and comparison, properties
- Collation coercion, and issues
- The new collation doesn’t pad anymore
- Behavior with indexes
- Consequences of the increase in (potential) size of char columns
- Information schema statistics caching
- GROUP BY not sorted anymore by default (+tooling)
- Schema migration tools support
- Obsolete Mac Homebrew default collation
- Good practice for (major/minor) upgrades: comparing the system variables
Handling the apt lock on Ubuntu Server installations (the infamous "Could not get lock /var/lib/apt/lists/lock")
When managing Ubuntu Server installations, for example image templates in the cloud, one of the main issues one comes across is apt locking, which causes the the annoying error
Could not get lock /var/lib/apt/lists/lock, typically “at the worst times”.
This seems to be a matter of discussion on the Stack Overflow network, but there are no working and stable solutions.
In order to get an idea of the confusion about the subject, check out the number and scope of solutions in this Stack Overflow question.
In this post I’ll talk about a few approaches, and the stable solution I’ve implemented.
Readers interested in just solving the problem can skip to the Eureka™ section.
Every month, I purge the files trashed more than one month before.
Since it’s been scientifically proven that manual operations cause PTSD in system administrators, I’ve made a script.
In this small article, I’ll explain some concepts involved, most notably, working with dates and numbers in Bash, and some other scripting-related concepts.
While researching a MySQL subject, I needed to process the MySQL server status variables (output), in order to extract and process some.
A computed value in particular (the max checkpoint age) required more elaborate processing.
This post explains a few Perl text processing functionalities (optionally aided by Awk), through many approaches to solving the problem.
- Input data, problem, and clarifications
- The approaches
- Conclusion: should cryptic (Perl) scripts be avoided in a team context?
Yesterday, I’ve officially released my ZFS Ubuntu installer.
This project will hopefully help the adoption of ZFS, at least by appealing curious/interested sysadmins.
Canonical is about to officially release an Ubuntu with built-in ZFS support, however, it has extremely limited functionality.
Create a VM, launch the program, and have fun playing with ZFS!
Although there is a complexity threshold for the convenience of shell scripting, there is still plenty that (in my opinion) can be done before hitting such ceiling.
In this brief article, I’ll explain how to use indirect references to write a function that prints the names and content of the variables passed; this is useful when writing debugging code for a script.
Debugging a live/stuck Ruby process is a well-known subject.
The way it’s generally exposed is simply a series of instructions and their outcome; given the expectation, this is fine of course, however, when I saw that a manual copy/paste operation was required, I decided to… step in (pun intended 😂).
This article adds only a few concepts, operatively speaking, but it clarifies all the concept involved, and employs neat approaches to accomplish the task. I will also employ several goodies available to Linux systems.
- A brief overview of debugging a process, and ptrace
- Using pgrep
- A brief overview of file descriptors
- Putting together Ruby and GDB (with fancy grep!)
- Basic GDB usage
- The procedure
- Safety of messing with file descriptors
- Other GDB/Ruby tools
In my latest sysadmin experimentations, I’ve configured the unattended upgrades on my new server (an Odroid H2 😍).
Among the other things, I had to add a PPA to the list of allowed origins to automatically upgrade. This required some interesting text processing, so I decided to dig into Perl’s text processing functionalities.
This post describes how to enable unattended upgrades for a PPA, while explaining several useful Perl features, in particular, how to process key/value tuples; a few regular expression functionalities are also used.
- A high level overview of how to enable unattended upgrades for a PPA
- Premises, and structuring the procedure
- The final commands
A functionality that I require, relatively frequently, when scripting, is to print the last N fields of a stream, with awk.
A typical example, is to copy part of the commits of a git
+ 81061edd2023c399539f1ff5cfdc267fd41c5c43 Ruby GUI development article: add `Some references` section + 5c60b7ef357683137b5f772f8590ab7d12c8e218 Ruby GUI development article: add `Footnotes` section + b6fe3469bc2ae59a7eba629c16ab11c67b7fbcbf Ruby GUI development article: add note about browser-based toolkits [...]
This post explains how to do it, with some extra goodies.
2019 is a very exciting year for people with at least a minor interest in storage. First, in May, the ZFS support for encryption and trimming has been added, with the release 0.8; then, in August, Canonical has officially announced the plan to add ZFS support to the installer¹ in the next Ubuntu release.
As of now, achieving a full-ZFS system (with a ZFS root (
/)) is possible, although non trivial. In this walkthrough, I’ve made the procedure as simple as possible, additionally setting up encryption and mirroring (RAID-1).
I’ll also give an introduction about the concepts involved, so that one has better awareness of the purpose of all the steps (but feel free to jump directly to the procedure).
Note that this guide is stable, but I’ll keep adding a few more sections and content in general.
- An introduction to the concepts involved
- Philosophy and limitations
- Requirements and specifications
Today we’ve had an emergency in production, which caused us to process log files.
An operation that comes very helpful in these situations is to quickly compute aggregates for values found in logs (or text files, in general).
This is possible, and actually easy, with the usual *nix tools; in this post I’ll explain three approaches to this problem.
Fairly recently, we’ve upgraded to MySQL 8; it’s been a relatively smooth transition, however, some minor differences needed to be handled. One of them is the behavior of trailing spaces.
Trailing spaces are a (not in a good way) surprising, but also widely covered argument. This article gives a short overview, and relates it to how this affects people upgrading to MySQL 8.0.
Unexpectedly, the SQL Standard (ISO/IEC 9075) documents, while public, are not free - they’re copyrighted, and available for purchase.
Still, some versions can be found on the web. PostgreSQL has a related section in their wiki, however, one link is out of date.
This is the up to date list of the documents, stored in the Wayback Machine, so that they’re permanent:
For reference, the most relevant part is #2.
During my last vacation, I wanted to watch some very old cartoons, during the daily break, on the digital media player that the apartment provided.
The player was very old, and couldn’t handle the video file (a modern MP4). Therefore, this was a good occasion to exercise the FFmpeg conversion and processing capabilities.
This post will give a glimpse of the tools that FFmpeg provides, showing how easy it is to perform the video/audio conversion, with extra processing.
I will also explain general concepts of media handling, like containers and encoding formats.
When it comes to configuring MySQL, a fundamental step is to find out which configuration files the MySQL server reads.
The operation itself is simple, however, if we want to script the operation, using text processing in a sharp way, it’s not immediate what the best solution is.
In this post I’ll explore the process of looking for a satisfying solution, going through grep, perl, and awk.
Recently, I needed to test some operations to be performed during the installation of Ubuntu on a system.
This requires multiple sessions and reboots, so retaining the changes on the installation media would considerably streamline the task.
VirtualBox doesn’t support booting a VM from a USB flash drive though, so a workaround is required.
This small article explains how to do this.
Due to some constraints, at Ticketsolve we sometimes need to work with an ancient file format: the Paradox Database.
This file format was in use between the 80s and 90s. In order to perform some operations on Paradox databases, nowadays, there are libraries based on the file format reverse engineering work by individual open source programmers, or ad hoc commercial programs.
Additionally, one can use Paradox 7, the reference commercial software originally published in 1992, now abandoned.
This software works good enough in Wine, however, the installer generally raises an error on installation, complaining that there isn’t enough disk space.
In this post we’ll use Radare2, one of the most powerful open source reverse engineering frameworks, in order to statically analyze and patch the installation binary, so that the pesky error is not triggered anymore.
There are no requirements for the reader; knowing x86/32 assembler and the PE executable format will improve the understanding, but it’s not a requirement by any means.
I wanted to tweak a script of mine; it included the conventional
find </path> -maxdepth 1 -type f. I wasn’t fully convinced it was the best choice, so I checked out what’s the
This post is about the research I’ve done; as usual, it’s an exercise in extensive usage of the available tools.
Note that I’ve been notified by a reader of the
-A, which simplifies the logic. I’ve kept both sections, for two reasons:
- the concepts not needed with the new approach are interesting to know regardless;
- in the new section I don’t explain in detail the concepts already explained in the old one.
We’re in the process of upgrading our MySQL databases from v5.7 to v8.0; since one of the differences in v8.0 is that the default encoding changed from
utf8mb4, and we had the conversion in plan anyway, we anticipated it and performed it as preliminary step for the upgrade.
This post describes in depth the overall experience, including tooling and pitfalls, and related subjects.
- Migration plan: overview and considerations
- !! COLLATION WARNING !!
- Free step: connection configuration
- Step 2: Preparing the the
- Step 3: Altering the schema and tables
- Notes about Mathias Bynens’ post on the same subject
Dropping a database column in production without waiting time and/or schema-aware code, on a MySQL/Rails setup
We recently had to drop a column in production, from a relatively large (order of 10⁷ records) table.
On modern MySQL setups, dropping a column doesn’t lock the table (it does, actually, but for a relatively short time), however, we wanted to improve a very typical Rails migration scenario in a few ways:
- offloading the column dropping time from the deploy;
- ensuring that in the time between the column is dropped and the app servers restarted, the app doesn’t raise errors due to the expectation that the column is present;
- not overloading the database with I/O.
I’ll give the Gh-ost tool a brief introduction, and show how to fulfill the above requirements in a simple way, by using this tool and an ActiveRecord flag.
This workflow can be applied to almost any table alteration scenario.
The bindings for the standard Ruby GUI toolkit, Tk, need some trickery in order to be installed on Ubuntu. This article shows how to do it.
I’ve recently moved from Bash to Zsh, and I needed to port my tab completion scripts. Zsh has a sophisticated built-in tab completion, however, the documentation is not very beginner-friendly; moreover, Bash scripts can be used with no or little change in Zsh. Therefore, I’ve opted for using them directly.
This article will explain how to write tab-completion scripts in any language, with an example in Ruby, and how to use them in both Bash and Zsh.
As typical of this blog, the script is also used as an exercise in shell scripting, therefore, it contains additional (arguably) useful/interesting commands/concepts.
Seldom, the subject of how to wipe the disk(s) of a headliness linux server comes up; there are a few resources online about it. This blog summarizes all the information around into a clean, stable and generic script that can be used in order to perform this task.
As typical of this blog, the script is also used as an exercise in shell scripting and system administration, therefore, it contains (arguably) useful/interesting commands/concepts.
Important! I’ve published an updated and extended guide on the same subject; check that out before reading this one!
Although the concepts involved in preparing a Debian (
.deb) source package and publishing it on an Ubuntu PPA are simple, due to the many moving parts involved, it’s not easy to find a single source of information.
This article provides all the information required to perform the process, using a trivial program as an example.
- About the approach and standards
- The procedure
- Preparing the source package
- Building the source package
- Uploading the package
- Deleting a package
- Using the PPA
With the large diffusion of SBCs [Single Board Computers], and subsequent maturation of their ecosystem, it’s now relatively easy to setup a home server.
I’ve had three SBCs until now; a Raspberry Pi 2 model B, a 3 model B, and recently, an Odroid XU4.
In this post, I’m going to share some considerations about their usage as home servers.
Updated on 3/Jul/2019: added new generation boards section.
- Considerations about new generation (A7x and Goldmont Plus) boards
- General characteristics of an SBC/home server
- Brief informations about ARM processors
- Raspberry Pi 3 Model B
- Odroid XU4
In system administration, it’s typical to perform long-running commands on remote hosts.
With GNU Screen and one supporting script, it’s possible to efficiently perform such operations, by running them asynchronously and receiving an email at the end, all in a single command.
Ruby GUI development is a seldom mentioned subject, but it has value. Probably after some Rails development (cough…), developing a desktop tool may be an interesting diversion (or even a requirement).
During the development of my PM-Spotlight desktop application, I evaluated most of the Desktop Ruby GUI toolkits, and prototyped the application with three of them (Shoes 3, FXRuby, and Tk).
This article presents a summary of what I’ve experienced (or gathered) while I was “Developing GUI applications with Ruby”!
Updated on 03/Oct/2019: Added update section about the article archival.
It’s very convenient to run service processes (for development purposes!) without admin permissions, rather starting it as system service.
This guide will show how to easily setup PostgreSQL (both via package and binary tarball) to be run by an unprivileged user, with the data in any directory owned by him/her.
GitLab offers a functionality for cherry picking a merge request (PR).
This functionality doesn’t exist in GitHub, and in Git, either; it is useful in some cases.
In this article I’ll explain some git fundamentals, and in the last section, how to cherry pick a PR/merge request.
In a project of mine, I’m implementing a feature that runs a background job in order to perform a search; in particular, it needs to support stopping at any time.
There is a variety of strategies to do this in Ruby. In this article I will expose what is the exact outcome of the common strategies, examining how this affects the underlying operating system.
The analysis is targeted to POSIX operating systems, although, at least part of it applies to Windows machines as well.
- Brief introduction to Ruby concurrency
- Technical context and preliminary notes
- Problem statement
- Effect of the common strategies on a Linux operating systems
- Introduction to process groups and their usage
This is the Part 3 (of 3) of the shell scripting adventures.
Updated on 11/Oct/2019: Use
mapfile for the check list widget returned entries.
The following subjects are described in this part:
- Introduction to Whiptail
- The mysterious redirections (
3>&1 1>&2 2>&3)
- Widgets, with snippets
- Other widgets
Since Whiptail is simple to use, the objective of this post is rather to show some useful code snippets/patterns.
This is the Part 2 (of 3) of the shell scripting adventures.
The following subjects are described in this part:
- Awk/sed/perl considerations
- Perl text processing
- Awk text processing
- Progress bars processing with awk (and stdbuf)
The examples are taken from my RPi VPN Router project installation script.
This is the Part 1 (of 3) of the shell scripting adventures.
The following subjects are described in this part:
- Associative arrays (hash maps)
- ANSI-C quoting
- Escape strings
- Expand strings into separate options
- Regular expressions matching
- Find a filename’s basename
- Replace the extension of a filename
- Cycle a multi-line variable
The examples are taken from my RPi VPN Router project installation script.
I’ve always thought of shell scripting as a second class scripting form, being awkward and limited. After a deep dive in my RPi VPN router project, I still think it’s awkward and limited, but I do appreciate it as first class choice under specific conditions.
Shell scripting generally can’t be disassociated from system/infrastructure administration, so developing the project has been actually, as a whole, a very interesting and pleasant undertaking.
This post lays the structure of the future posts I’ll publish about the experience.
Mysql 5.7 added native support for JSON data type. This opens up several interesting possibilities, but it’s not natively supported in Rails 4 (only in v5).
I’ve released a gem, JSON on Rails, for supporting this functionality on Rails 4.
This article describes how the gem works, for those interested in the inner workings, or who want to implement the functionality by themselves.
MySQL 5.7.19 fixes a quite dangerous functionality that causes corruption of a slave when changing the delay (
CHANGE MASTER TO MASTER_DELAY=<seconds>) while the slave threads are stopped; since one wouldn’t expect this condition to cause harm, users of such setup should upgrade, if possible.
Users trying to perform the update on Ubuntu 14.04 LTS will face the mysql service not starting.
In my VGA Passthrough guide, I explain how to configure an Ubuntu machine for VFIO.
With the release of QEMU 2.10, some bugs in the OVMF firmware surfaced, which make Windows guests unstable; such bugs have been fixed in the master branch of the EDK II Project repository, so, in order to use QEMU 2.10, it’s required to build the firmware from scratch.
Such data type is very interesting, although it requires a careful examination, since it has very important design implications.
Recently, we decided to clean our data model, in particular, the OLTP section of our schema. We have a reasonably well structured model, but it falls short when it comes to the data type definitions.
In this article we explore the storage requirements of a (InnoDB) table of ours, and the impact of choosing more strictly defined columns.