<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Mysql on ege.dev</title>
    <link>https://ege.dev/tags/mysql/</link>
    <description>Hello. I&#39;m Ege.</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <copyright>&#169; 2026 ege.dev</copyright>
    <lastBuildDate>Tue, 19 May 2026 18:15:35 +0000</lastBuildDate>
    <atom:link href="https://ege.dev/tags/mysql/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Point-in-time recovery for MySQL on Kubernetes</title>
      <link>https://ege.dev/entries/2026/03/point-in-time-recovery-for-mysql-on-kubernetes/</link>
      <pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">https://ege.dev/entries/2026/03/point-in-time-recovery-for-mysql-on-kubernetes/</guid>
      <description>&lt;p&gt;Since the v1.0.0 release of the new MySQL Operator (K8SPS), point-in-time recovery (PiTR) has been the most anticipated feature. Naturally, we decided to implement it in the upcoming v1.1.0 release.&lt;/p&gt;
&lt;p&gt;PiTR relies on two processes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Reliably collecting binary logs from MySQL servers and storing them somewhere safe&lt;/li&gt;
&lt;li&gt;When the recovery is triggered, applying those binary logs up to a specific point&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;collecting-binary-logs&#34;&gt;Collecting binary logs&lt;/h2&gt;
&lt;p&gt;Our Galera replication-based MySQL Operator (K8SPXC) has a binary log collector that was developed by the Cloud Team. It has worked reliably for years but has a certain limitation that is inherent in its design: it depends on flushing the binary logs to collect them. This leads to huge numbers of binary logs on the MySQL server, which becomes a headache after running the collector for a few weeks. We mitigated this for the users by maintaining a cache for binary logs, but it didn&amp;rsquo;t remove the pain—it just became ours.&lt;/p&gt;
&lt;p&gt;At Percona, #FindABetterWay is one of our core values. In the spirit of finding a better way, when we first started to think about PiTR in K8SPS, we decided to improve the process of collecting binary logs. These discussions eventually led to the birth of a new product: &lt;a href=&#34;https://github.com/Percona-Lab/percona-binlog-server&#34;&gt;Percona Binlog Server (PBS)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;PBS works by connecting to the MySQL server as a replica and streaming events. It either uploads these events to S3 or stores them on the filesystem. It supports replication source switchovers and is able to continue from where it left off. On top of these, it provides helper commands to search for a particular GTID or timestamp in the collected binary logs.&lt;/p&gt;
&lt;h2 id=&#34;applying-binary-logs&#34;&gt;Applying binary logs&lt;/h2&gt;
&lt;p&gt;The official &lt;a href=&#34;https://dev.mysql.com/doc/refman/8.4/en/point-in-time-recovery-binlog.html&#34;&gt;MySQL docs&lt;/a&gt; suggest converting each binary log to text using &lt;code&gt;mysqlbinlog&lt;/code&gt; and piping them into the &lt;code&gt;mysql&lt;/code&gt; client for PiTR. This is already what we do in K8SPXC.&lt;/p&gt;
&lt;p&gt;I decided to check if there&amp;rsquo;s a better way. First, I checked old posts on the Percona Blog to see if our experts had written anything about a different PiTR approach. It&amp;rsquo;s not surprising that they did. &lt;a href=&#34;https://www.percona.com/blog/mysql-point-in-time-recovery-right-way/&#34;&gt;Marcelo&lt;/a&gt; wrote about an approach leveraging replication appliers for recovery. It seemed much better than piping &lt;code&gt;mysqlbinlog&lt;/code&gt; output into the client, since with replication we can have multithreading and parallel appliers for recovery. My only problem with this approach was that it required two &lt;code&gt;mysqld&lt;/code&gt; instances. Of course it&amp;rsquo;s possible, but I would love to not have to care about the state of two MySQL servers.&lt;/p&gt;
&lt;p&gt;Luckily, &lt;a href=&#34;https://www.percona.com/blog/mysql-point-in-time-recovery-right-way/#comment-10968578&#34;&gt;lefred&lt;/a&gt; commented that there&amp;rsquo;s an &lt;a href=&#34;https://lefred.be/content/howto-make-mysql-point-in-time-recovery-faster/&#34;&gt;&amp;ldquo;even better&amp;rdquo; approach&lt;/a&gt; that requires only one MySQL server!&lt;/p&gt;
&lt;p&gt;At a high level, the process looks like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Restore the full backup into the MySQL datadir&lt;/li&gt;
&lt;li&gt;Start a temporary &lt;code&gt;mysqld&lt;/code&gt; instance&lt;/li&gt;
&lt;li&gt;Download binary logs and put them as relay logs in the datadir&lt;/li&gt;
&lt;li&gt;Start replication via &lt;code&gt;CHANGE REPLICATION SOURCE TO RELAY_LOG_FILE=..., SOURCE_HOST=&#39;dummy&#39;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Start applying binary logs via &lt;code&gt;START REPLICA SQL_THREAD UNTIL &amp;lt;GTID&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Wait for the SQL thread to stop&lt;/li&gt;
&lt;li&gt;&lt;code&gt;STOP REPLICA; RESET REPLICA ALL;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I have already created an unpolished but working &lt;a href=&#34;https://github.com/percona/percona-server-mysql-operator/pull/1252&#34;&gt;PoC&lt;/a&gt;. There is also an &lt;a href=&#34;https://github.com/percona/percona-server-mysql-operator/pull/1251&#34;&gt;RFC&lt;/a&gt; for explaining various decisions and tracking open questions that need answers. There&amp;rsquo;s still work to do, but I&amp;rsquo;m confident that this approach is good and we&amp;rsquo;ll release this as a &lt;em&gt;tech preview&lt;/em&gt; in the upcoming v1.1.0 release. If you have thoughts on the RFC or want to try the PoC, we&amp;rsquo;d love to hear your feedback.&lt;/p&gt;
</description>
      <category>mysql</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>gremlins in HAProxy</title>
      <link>https://ege.dev/entries/2026/03/gremlins-in-haproxy/</link>
      <pubDate>Thu, 12 Mar 2026 00:00:00 +0000</pubDate>
      <guid isPermaLink="false">https://ege.dev/entries/2026/03/gremlins-in-haproxy/</guid>
      <description>&lt;p&gt;We are in the process of certifying our operators for &lt;code&gt;&amp;lt;redacted&amp;gt;&lt;/code&gt;. We started
with PostgreSQL Operator and it worked just fine without any adjustments. Then
we moved on to our MySQL Operators and it surfaced a problem in HAProxy.&lt;/p&gt;
&lt;p&gt;HAProxy is used by default in our MySQL clusters. They sit in front of MySQL
instances as the proxy to have read/write splitting. We have our own external
scripts to perform checks for each backend for determining if a MySQL server is
good for that particular backend.&lt;/p&gt;
&lt;p&gt;After deploying the operator on &lt;code&gt;&amp;lt;redacted&amp;gt;&lt;/code&gt;, we realized that our HAProxy pods are
failing to get ready because all external checks are failing due to timeouts.
But why?&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s gotta be the DNS. It&amp;rsquo;s always DNS, isn&amp;rsquo;t it? Turns out, no. I tested DNS
queries from the HAProxy container and it seems they were fast.&lt;/p&gt;
&lt;p&gt;Could this be AppArmor? Maybe &lt;code&gt;&amp;lt;redacted&amp;gt;&lt;/code&gt; has stricter AppArmor profiles? I configured
HAProxy pods to be &lt;code&gt;Unconfined&lt;/code&gt;. It didn&amp;rsquo;t help either.&lt;/p&gt;
&lt;p&gt;Then I decided to increase the timeout from 10 seconds to 30 seconds, just to
see how much time the script needs to finish. To my surprise, the script was
taking 810 milliseconds to finish! How could a check time out in 10 seconds but
finish in less than a second with 30 seconds timeout?&lt;/p&gt;
&lt;p&gt;In every deep debugging session, there is a moment when engineers start to
believe in spiritual beings or gremlins who mess with the software in the
system. One needs to resist this temptation of irrationality. In computers
there&amp;rsquo;s always a rational explanation for problems, it&amp;rsquo;s just very deep and
caused by unlucky combinations of design choices and/or bugs.&lt;/p&gt;
&lt;p&gt;At this point I decided to attach a debug container into the pod and check what
HAProxy is doing with strace. This resulted in the first breakthrough of the
problem: the child process of HAProxy that runs the external check command was
doing shitloads of poll syscalls until it was killed due to timeout. It wasn&amp;rsquo;t
even running the script, it was simply stuck.&lt;/p&gt;
&lt;p&gt;This realization made me shift my focus to HAProxy itself. I started to read
the source code to see what&amp;rsquo;s going on.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/haproxy/haproxy/blob/v2.8.0/src/extcheck.c#L414-L427&#34;&gt;src/extcheck.c&lt;/a&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;int fd;
sa_family_t family;

/* close all FDs. Keep stdin/stdout/stderr in verbose mode */
fd = (global.mode &amp;amp; (MODE_QUIET|MODE_VERBOSE)) == MODE_QUIET ? 0 : 3;

my_closefrom(fd);

/* restore the initial FD limits */
limit.rlim_cur = rlim_fd_cur_at_boot;
limit.rlim_max = rlim_fd_max_at_boot;
if (raise_rlim_nofile(NULL, &amp;amp;limit) != 0) {
	getrlimit(RLIMIT_NOFILE, &amp;amp;limit);
	ha_warning(&amp;#34;External check: failed to restore initial FD limits (cur=%u max=%u), using cur=%u max=%u\n&amp;#34;,
		   rlim_fd_cur_at_boot, rlim_fd_max_at_boot,
		   (unsigned int)limit.rlim_cur, (unsigned int)limit.rlim_max);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;HAProxy attempts to close all FDs. What does &lt;em&gt;all&lt;/em&gt; mean? And then it restores
limits to some value? What&amp;rsquo;s that value?&lt;/p&gt;
&lt;p&gt;All FDs means closing all from FD 0 to FD soft limit. &lt;code&gt;my_closefrom&lt;/code&gt; function
first polls the FD and then closes it if poll doesn&amp;rsquo;t fail with &lt;code&gt;POLLNVAL&lt;/code&gt;. OK,
this explains the excessive polling I see with strace. But it&amp;rsquo;s the default
HAProxy behavior for a long time, why didn&amp;rsquo;t we see the same problem on some
other platform, i.e GKE?&lt;/p&gt;
&lt;p&gt;The answer is simple. Turns out, &lt;code&gt;&amp;lt;redacted&amp;gt;&lt;/code&gt; has a much higher soft limit than GKE. On
GKE &lt;code&gt;ulimit -n&lt;/code&gt; returns 1048576, on &lt;code&gt;&amp;lt;redacted&amp;gt;&lt;/code&gt; 1073741816! But still there was
something that troubled me at this point: I vaguely remembered a configuration
option in HAProxy that limits the number of FDs that the process will use. The
option is &lt;code&gt;fd-hard-limit&lt;/code&gt; and
&lt;a href=&#34;https://docs.haproxy.org/2.8/configuration.html#fd-hard-limit&#34;&gt;docs&lt;/a&gt; say its
default value is 1048576. If it had any effect, I wouldn&amp;rsquo;t have seen any
problems. Something was wrong in HAProxy.&lt;/p&gt;
&lt;p&gt;Remember that the external check process was doing something to restore limits
to some value assigned at boot? Those values are assigned in the &lt;code&gt;main&lt;/code&gt;
function here:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/haproxy/haproxy/blob/v2.8.0/src/haproxy.c#L3263-L3269&#34;&gt;src/haproxy.c&lt;/a&gt;&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/* take a copy of initial limits before we possibly change them */
getrlimit(RLIMIT_NOFILE, &amp;amp;limit);

if (limit.rlim_max == RLIM_INFINITY)
	limit.rlim_max = limit.rlim_cur;
rlim_fd_cur_at_boot = limit.rlim_cur;
rlim_fd_max_at_boot = limit.rlim_max;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&#34;https://github.com/haproxy/haproxy/blob/v2.8.0/src/haproxy.c#L3311-L3312&#34;&gt;The
code&lt;/a&gt;
that limits FDs with &lt;code&gt;fd-hard-limit&lt;/code&gt; is a few lines below:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;if (global.fd_hard_limit &amp;amp;&amp;amp; limit.rlim_cur &amp;gt; global.fd_hard_limit)
	limit.rlim_cur = global.fd_hard_limit;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This means external checks restore limits to the value unbounded by
&lt;code&gt;fd-hard-limit&lt;/code&gt;. Oh, this looks like &lt;a href=&#34;https://github.com/haproxy/haproxy/issues/3299&#34;&gt;a
bug&lt;/a&gt; in HAProxy and explains
why we had this issue!&lt;/p&gt;
</description>
      <category>mysql</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Cluster Statuses in Percona Kubernetes Operators</title>
      <link>https://ege.dev/entries/2021/07/cluster-statuses-in-percona-kubernetes-operators/</link>
      <pubDate>Wed, 21 Jul 2021 15:10:57 +0300</pubDate>
      <guid isPermaLink="false">https://ege.dev/entries/2021/07/cluster-statuses-in-percona-kubernetes-operators/</guid>
      <description>&lt;p&gt;In Kubernetes, all resources have a status field separated from their spec. The
status field is an interface both for humans or applications to read the
perceived state of the resource.&lt;/p&gt;
&lt;p&gt;When you deploy our Percona Kubernetes Operators –  Percona Operator for
MongoDB or Percona Operator for MySQL – in your Kubernetes cluster, you’re
creating a custom resource (CR for short) and it has its own status, too. Since
Kubernetes operators mimic the human operator and aim to have the required
expertise to run software in a Kubernetes cluster; the status of the custom
resources should be smart.&lt;/p&gt;
&lt;p&gt;You can get cluster status with the commands below, or via (Kubernetes API) for
Percona Operator for MySQL:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;% kubectl get pxc
NAME            ENDPOINT                                   STATUS   PXC   PROXYSQL   HAPROXY   AGE
lisette-18537   lisette-18537-haproxy.subjectivism-22940   ready    3                3         87m

% kubectl get pxc &amp;lt;cluster-name&amp;gt; -o jsonpath=&amp;#39;{.status}&amp;#39;
{
  &amp;#34;backup&amp;#34;: {
    &amp;#34;version&amp;#34;: &amp;#34;8.0.23&amp;#34;
  },
  &amp;#34;conditions&amp;#34;: [
    {
      &amp;#34;lastTransitionTime&amp;#34;: &amp;#34;2021-07-12T13:13:46Z&amp;#34;,
      &amp;#34;status&amp;#34;: &amp;#34;True&amp;#34;,
      &amp;#34;type&amp;#34;: &amp;#34;initializing&amp;#34;
    }
  ],
  &amp;#34;haproxy&amp;#34;: {
    &amp;#34;labelSelectorPath&amp;#34;: &amp;#34;...&amp;#34;,
    &amp;#34;ready&amp;#34;: 3,
    &amp;#34;size&amp;#34;: 3,
    &amp;#34;status&amp;#34;: &amp;#34;ready&amp;#34;
  },
  &amp;#34;host&amp;#34;: &amp;#34;lisette-18537-haproxy.subjectivism-22940&amp;#34;,
  &amp;#34;logcollector&amp;#34;: {
    &amp;#34;version&amp;#34;: &amp;#34;1.8.0&amp;#34;
  },
  &amp;#34;observedGeneration&amp;#34;: 2,
  &amp;#34;pmm&amp;#34;: {
    &amp;#34;version&amp;#34;: &amp;#34;2.12.0&amp;#34;
  },
  &amp;#34;proxysql&amp;#34;: {},
  &amp;#34;pxc&amp;#34;: {
    &amp;#34;image&amp;#34;: &amp;#34;percona/percona-xtradb-cluster:8.0.22-13.1&amp;#34;,
    &amp;#34;labelSelectorPath&amp;#34;: &amp;#34;...&amp;#34;,
    &amp;#34;ready&amp;#34;: 2,
    &amp;#34;size&amp;#34;: 3,
    &amp;#34;status&amp;#34;: &amp;#34;initializing&amp;#34;,
    &amp;#34;version&amp;#34;: &amp;#34;8.0.22-13.1&amp;#34;
  },
  &amp;#34;ready&amp;#34;: 5,
  &amp;#34;size&amp;#34;: 6,
  &amp;#34;state&amp;#34;: &amp;#34;initializing&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And for Percona Operator for MongoDB:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;% kubectl get psmdb
NAME             ENDPOINT                                                     STATUS   AGE
cynodont-26997   cynodont-26997-mongos.subjectivism-22940.svc.cluster.local   ready    85m


% kubectl get psmdb &amp;lt;cluster-name&amp;gt; -o jsonpath=&amp;#39;{.status}&amp;#39;
{
  &amp;#34;conditions&amp;#34;: [
    {
      &amp;#34;lastTransitionTime&amp;#34;: &amp;#34;2021-07-12T13:13:39Z&amp;#34;,
      &amp;#34;status&amp;#34;: &amp;#34;True&amp;#34;,
      &amp;#34;type&amp;#34;: &amp;#34;initializing&amp;#34;
    }
  ],
  &amp;#34;host&amp;#34;: &amp;#34;cynodont-26997-mongos.subjectivism-22940.svc.cluster.local&amp;#34;,
  &amp;#34;mongoImage&amp;#34;: &amp;#34;percona/percona-server-mongodb:4.4.6-8&amp;#34;,
  &amp;#34;mongoVersion&amp;#34;: &amp;#34;4.4.6-8&amp;#34;,
  &amp;#34;mongos&amp;#34;: {
    &amp;#34;ready&amp;#34;: 1,
    &amp;#34;size&amp;#34;: 3,
    &amp;#34;status&amp;#34;: &amp;#34;initializing&amp;#34;
  },
  &amp;#34;observedGeneration&amp;#34;: 2,
  &amp;#34;ready&amp;#34;: 3,
  &amp;#34;replsets&amp;#34;: {
    &amp;#34;cfg&amp;#34;: {
      &amp;#34;ready&amp;#34;: 1,
      &amp;#34;size&amp;#34;: 3,
      &amp;#34;status&amp;#34;: &amp;#34;initializing&amp;#34;
    },
    &amp;#34;rs0&amp;#34;: {
      &amp;#34;initialized&amp;#34;: true,
      &amp;#34;ready&amp;#34;: 2,
      &amp;#34;size&amp;#34;: 3,
      &amp;#34;status&amp;#34;: &amp;#34;initializing&amp;#34;
    }
  },
  &amp;#34;size&amp;#34;: 6,
  &amp;#34;state&amp;#34;: &amp;#34;initializing&amp;#34;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see there are several fields in the output: conditions, cluster
size, number of ready cluster members, statuses and versions of different
components, and the “state”. In the following sections, we’ll take a look at
every possible value of the state field.&lt;/p&gt;
&lt;h2 id=&#34;initializing&#34;&gt;Initializing&lt;/h2&gt;
&lt;p&gt;While the cluster is progressing to readiness, CR status is “initializing”. It
includes creating the cluster, scaling it up or down, and updating the CR that
triggers a rolling restart of pods (for instance updating Percona Operator for
MySQL memory limits).&lt;/p&gt;
&lt;p&gt;Percona Operator for MongoDB also reconfigures the replica set config if
necessary (for instance it adds the new pods as members to replset or removes
terminated ones). Replica set in MongoDB is a set of servers that implements
replication and automatic failover. Although they have the same name, it’s
different from the Kubernetes replica set. While this configuration is
happening or if there is an unknown/unpredicted error during it, the status is
also “initializing”.&lt;/p&gt;
&lt;p&gt;Since version 1.7.0, the Percona Operator for MySQL can handle full crash
recovery if necessary. If a pod waits for the recovery, the cluster status is
“initializing”.&lt;/p&gt;
&lt;h2 id=&#34;ready&#34;&gt;Ready&lt;/h2&gt;
&lt;p&gt;The operator keeps track of the status of each component in the cluster.
Percona Operator for MongoDB has the following components:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;mongod StatefulSet&lt;/li&gt;
&lt;li&gt;configsvr StatefulSet if sharding is enabled&lt;/li&gt;
&lt;li&gt;mongos Deployment if sharding is enabled&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Percona Operator for MySQL components:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;PXC StatefulSet&lt;/li&gt;
&lt;li&gt;HAProxy StatefulSet if enabled&lt;/li&gt;
&lt;li&gt;ProxySQL StatefulSet if enabled&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All components need to be in “ready” status for CR to be “ready”. If the number
of ready pods controlled by the stateful set reaches the desired number, the
operator marks the component as ready. The readiness of the pods is tracked by
Kubernetes using readiness probes for each container in the pod. For example,
for a Percona XtraDB Cluster container to be ready “wsrep_cluster_status” needs
to be “Primary” and “wsrep_local_state” should be “Synced” or “Donor”. For a
Percona Server for MongoDB container to be ready, accepting TCP connections on
27017 is enough.&lt;/p&gt;
&lt;p&gt;But ready as the CR status means more than that. CR “ready” means the cluster
(Percona Server for MongoDB or Percona XtraDB Cluster) is up and running and
ready to receive traffic. So, even if all components are ready, the cluster
status can be “initializing”. In the Percona Operator for MongoDB, the replica
set needs to be initialized and its config up-to-date. Also, with the 1.9.0
release of both operators, the load balancer needs to be ready if the cluster
is exposed with &lt;code&gt;exposeType: LoadBalancer&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;stopping&#34;&gt;Stopping&lt;/h2&gt;
&lt;p&gt;Version 1.9.0 introduced two new statuses:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stopping&lt;/li&gt;
&lt;li&gt;Paused&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Stopping means the cluster is paused or deleted and its pods are terminating right now.&lt;/p&gt;
&lt;p&gt;If you run &lt;code&gt;kubectl delete psmdb &amp;lt;cluster-name&amp;gt;&lt;/code&gt; or `kubectl delete pxc
&lt;cluster-name&gt;`` the resource can be deleted quickly without a chance to see
“stopping” status. If you had finalizers (for example
“delete-pxc-pods-in-order” in Percona Operator for MySQL) deletion will be
blocked until the finalizer list is exhausted and you can observe “stopping”
status.&lt;/p&gt;
&lt;h2 id=&#34;paused&#34;&gt;Paused&lt;/h2&gt;
&lt;p&gt;Once the cluster is paused and all pods are terminated, the CR status becomes “paused”.&lt;/p&gt;
&lt;p&gt;To pause the cluster: &lt;code&gt;kubectl patch &amp;lt;psmdb|pxc&amp;gt; &amp;lt;cluster-name&amp;gt; --type=merge -p &#39;{&amp;quot;spec&amp;quot;: {&amp;quot;pause&amp;quot;: true}}&#39;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Keep in mind, when the cluster is paused and exposeType is LoadBalancer – Load
balancers are still there and you continue to pay for them.&lt;/p&gt;
&lt;h2 id=&#34;error&#34;&gt;Error&lt;/h2&gt;
&lt;p&gt;Before 1.9.0, “error” status could mean two different things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;An error occurred in the operator during the reconciliation of the CR&lt;/li&gt;
&lt;li&gt;One or more pods in a component are not schedulable&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With 1.9.0, the “error” status means only the operator errors. If there is an
unschedulable pod, the cluster’s status will be initializing. If the cluster is
stuck in initializing for too long, it’s better to check the operator logs to
investigate.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;% kubectl logs &amp;lt;operator-pod-name&amp;gt;
...
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1626095618.9982307,&amp;#34;logger&amp;#34;:&amp;#34;controller_psmdb&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;Created a new mongo key&amp;#34;,&amp;#34;Request.Namespace&amp;#34;:&amp;#34;subjectivism-22940&amp;#34;,&amp;#34;Request.Name&amp;#34;:&amp;#34;cynodont-26997&amp;#34;,&amp;#34;KeyName&amp;#34;:&amp;#34;cynodont-26997-mongodb-keyfile&amp;#34;}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1626095619.0032709,&amp;#34;logger&amp;#34;:&amp;#34;controller_psmdb&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;Created a new mongo key&amp;#34;,&amp;#34;Request.Namespace&amp;#34;:&amp;#34;subjectivism-22940&amp;#34;,&amp;#34;Request.Name&amp;#34;:&amp;#34;cynodont-26997&amp;#34;,&amp;#34;KeyName&amp;#34;:&amp;#34;cynodont-26997-mongodb-encryption-key&amp;#34;}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1626095687.3783236,&amp;#34;logger&amp;#34;:&amp;#34;controller_psmdb&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;initiating replset&amp;#34;,&amp;#34;replset&amp;#34;:&amp;#34;rs0&amp;#34;,&amp;#34;pod&amp;#34;:&amp;#34;cynodont-26997-rs0-1&amp;#34;}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1626095694.020591,&amp;#34;logger&amp;#34;:&amp;#34;controller_psmdb&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;replset was initialized&amp;#34;,&amp;#34;replset&amp;#34;:&amp;#34;rs0&amp;#34;,&amp;#34;pod&amp;#34;:&amp;#34;cynodont-26997-rs0-1&amp;#34;}
{&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1626095694.622869,&amp;#34;logger&amp;#34;:&amp;#34;controller_psmdb&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;failed to reconcile cluster&amp;#34;,&amp;#34;Request.Namespace&amp;#34;:&amp;#34;subjectivism-22940&amp;#34;,&amp;#34;Request.Name&amp;#34;:&amp;#34;cynodont-26997&amp;#34;,&amp;#34;replset&amp;#34;:&amp;#34;rs0&amp;#34;,&amp;#34;error&amp;#34;:&amp;#34;undefined state of the replset member cynodont-26997-rs0-0.cynodont-26997-rs0.subjectivism-22940.svc.cluster.local:27017: 6&amp;#34;,&amp;#34;errorVerbose&amp;#34;:&amp;#34;undefined state of the replset member cynodont-26997-rs0-0.cynodont-26997-rs0.subjectivism-22940.svc.cluster.local:27017: 6\ngithub.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb.(*ReconcilePerconaServerMongoDB).reconcileCluster\n\t/go/src/github.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb/mgo.go:210\ngithub.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb.(*ReconcilePerconaServerMongoDB).Reconcile\n\t/go/src/github.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb/psmdb_controller.go:449\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:256\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:232\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).worker\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:211\nk8s.io/apimachinery/pkg/util/wait.JitterUntil.func1\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:152\nk8s.io/apimachinery/pkg/util/wait.JitterUntil\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:153\nk8s.io/apimachinery/pkg/util/wait.Until\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1371&amp;#34;,&amp;#34;stacktrace&amp;#34;:&amp;#34;github.com/go-logr/zapr.(*zapLogger).Error\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/github.com/go-logr/zapr/zapr.go:128\ngithub.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb.(*ReconcilePerconaServerMongoDB).Reconcile\n\t/go/src/github.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb/psmdb_controller.go:451\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:256\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:232\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).worker\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:211\nk8s.io/apimachinery/pkg/util/wait.JitterUntil.func1\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:152\nk8s.io/apimachinery/pkg/util/wait.JitterUntil\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:153\nk8s.io/apimachinery/pkg/util/wait.Until\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88&amp;#34;}
% kubectl logs &amp;lt;operator-pod-name&amp;gt;
 
...
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1626095618.9982307,&amp;#34;logger&amp;#34;:&amp;#34;controller_psmdb&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;Created a new mongo key&amp;#34;,&amp;#34;Request.Namespace&amp;#34;:&amp;#34;subjectivism-22940&amp;#34;,&amp;#34;Request.Name&amp;#34;:&amp;#34;cynodont-26997&amp;#34;,&amp;#34;KeyName&amp;#34;:&amp;#34;cynodont-26997-mongodb-keyfile&amp;#34;}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1626095619.0032709,&amp;#34;logger&amp;#34;:&amp;#34;controller_psmdb&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;Created a new mongo key&amp;#34;,&amp;#34;Request.Namespace&amp;#34;:&amp;#34;subjectivism-22940&amp;#34;,&amp;#34;Request.Name&amp;#34;:&amp;#34;cynodont-26997&amp;#34;,&amp;#34;KeyName&amp;#34;:&amp;#34;cynodont-26997-mongodb-encryption-key&amp;#34;}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1626095687.3783236,&amp;#34;logger&amp;#34;:&amp;#34;controller_psmdb&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;initiating replset&amp;#34;,&amp;#34;replset&amp;#34;:&amp;#34;rs0&amp;#34;,&amp;#34;pod&amp;#34;:&amp;#34;cynodont-26997-rs0-1&amp;#34;}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1626095694.020591,&amp;#34;logger&amp;#34;:&amp;#34;controller_psmdb&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;replset was initialized&amp;#34;,&amp;#34;replset&amp;#34;:&amp;#34;rs0&amp;#34;,&amp;#34;pod&amp;#34;:&amp;#34;cynodont-26997-rs0-1&amp;#34;}
{&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1626095694.622869,&amp;#34;logger&amp;#34;:&amp;#34;controller_psmdb&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;failed to reconcile cluster&amp;#34;,&amp;#34;Request.Namespace&amp;#34;:&amp;#34;subjectivism-22940&amp;#34;,&amp;#34;Request.Name&amp;#34;:&amp;#34;cynodont-26997&amp;#34;,&amp;#34;replset&amp;#34;:&amp;#34;rs0&amp;#34;,&amp;#34;error&amp;#34;:&amp;#34;undefined state of the replset member cynodont-26997-rs0-0.cynodont-26997-rs0.subjectivism-22940.svc.cluster.local:27017: 6&amp;#34;,&amp;#34;errorVerbose&amp;#34;:&amp;#34;undefined state of the replset member cynodont-26997-rs0-0.cynodont-26997-rs0.subjectivism-22940.svc.cluster.local:27017: 6\ngithub.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb.(*ReconcilePerconaServerMongoDB).reconcileCluster\n\t/go/src/github.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb/mgo.go:210\ngithub.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb.(*ReconcilePerconaServerMongoDB).Reconcile\n\t/go/src/github.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb/psmdb_controller.go:449\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:256\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:232\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).worker\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:211\nk8s.io/apimachinery/pkg/util/wait.JitterUntil.func1\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:152\nk8s.io/apimachinery/pkg/util/wait.JitterUntil\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:153\nk8s.io/apimachinery/pkg/util/wait.Until\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1371&amp;#34;,&amp;#34;stacktrace&amp;#34;:&amp;#34;github.com/go-logr/zapr.(*zapLogger).Error\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/github.com/go-logr/zapr/zapr.go:128\ngithub.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb.(*ReconcilePerconaServerMongoDB).Reconcile\n\t/go/src/github.com/percona/percona-server-mongodb-operator/pkg/controller/perconaservermongodb/psmdb_controller.go:451\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:256\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:232\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).worker\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:211\nk8s.io/apimachinery/pkg/util/wait.JitterUntil.func1\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:152\nk8s.io/apimachinery/pkg/util/wait.JitterUntil\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:153\nk8s.io/apimachinery/pkg/util/wait.Until\n\t/go/src/github.com/percona/percona-server-mongodb-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88&amp;#34;}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can try new statuses in version 1.9.0 of both Percona Operator for MongoDB
and Percona Operator for MySQL. Percona Operator for MongoDB was released in
June and Percona Operator for MySQL is on the way.&lt;/p&gt;
</description>
      <category>kubernetes</category>
      <category>mongodb</category>
      <category>mysql</category>
    </item>
  </channel>
</rss>
